Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oztxs-0005b6-N5 for pgsql-hackers@arkaria.postgresql.org; Tue, 29 Nov 2022 06:19:33 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1oztxq-0007YO-LX for pgsql-hackers@arkaria.postgresql.org; Tue, 29 Nov 2022 06:19:30 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oztxp-0007YE-6P for pgsql-hackers@lists.postgresql.org; Tue, 29 Nov 2022 06:19:30 +0000 Received: from out1-smtp.messagingengine.com ([66.111.4.25]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oztxl-0005hS-JQ for pgsql-hackers@lists.postgresql.org; Tue, 29 Nov 2022 06:19:28 +0000 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 38D4C5C0125; Tue, 29 Nov 2022 01:19:24 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Tue, 29 Nov 2022 01:19:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=paquier.xyz; h= cc:cc:content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm1; t=1669702764; x=1669789164; bh=O2X+0zjEPA 0rVNusy3rLCMtJJEw+lYHK5P9hob9jYZs=; b=nIFFnT7xf9ia5IVlQf6WQYEBBn +8wLC2tTjsZrQvCiyfPpFx3nDVwVR6/QiSxDprDrJahwKed8ySzz+LrY9BvKOBOj FQSboqAc/2ypSMUlHwDVgrXfRNGTC/0xEcctRjysgLLIcCWvhWYseuFhtCzPalI+ aFwkUE8a6za/PCrjiwICliThslPMgZCGIjnkOsEdAysC9GyHElL2Sj089P1g1R+6 uGm9JwuYsZc3Bje6y5Nv1+yXixieZLu3hnRl2AFKLqqy9KeEROP1bTpBp3fjyluY dRaCG1h3r+bCBm82fecaddcbiksEDbwd/owi5w7wf+8JHqvBxPLoXOMLlXpQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:date:date:feedback-id :feedback-id:from:from:in-reply-to:in-reply-to:message-id :mime-version:references:reply-to:sender:subject:subject:to:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1669702764; x=1669789164; bh=O2X+0zjEPA0rVNusy3rLCMtJJEw+ lYHK5P9hob9jYZs=; b=jhQzW2Y4KmOi3TR16XYHVA2jVPk1AhRXJHeR/C1i+EC1 3nq3fmX/kXMsUnMu7om6/czy+vAcsOPoLCuLMSlg2GeIKVBVJjyJvbN88fgP2fIP R9KBM2L6c80KXEgIm1MYTt0pccMbGEF0oUFrqQMBM7F/nQIGhEuE3LgRKHITuRBL rk0DO/rkVka7rEgCVyz4ZMn16ck71qKvR63jl/T+VsAVG882042vGoB1cyERCEkk 3wwrj4q51UoZ2qk3bxhJRMFvq0ZaZC9RiKRAPUT9vqENAsBNoDu5LLTy4z7QQxD6 iBczCoeVogNwcBEDScvhMEZDDqZ0CmMWps/yh1V6jg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvgedrjeefgdelhecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenfg hrlhcuvffnffculdefhedmnecujfgurhepfffhvfevuffkfhggtggujgesghdtreertddt vdenucfhrhhomhepofhitghhrggvlhcurfgrqhhuihgvrhcuoehmihgthhgrvghlsehprg hquhhivghrrdighiiiqeenucggtffrrghtthgvrhhnpeetleeifedufffhhfdtteelgeeg geffhfekueevteeigfduudevudetgfegiedvjeenucevlhhushhtvghrufhiiigvpedtne curfgrrhgrmhepmhgrihhlfhhrohhmpehmihgthhgrvghlsehprghquhhivghrrdighiii X-ME-Proxy: Feedback-ID: i0fe9450f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 29 Nov 2022 01:19:21 -0500 (EST) Date: Tue, 29 Nov 2022 15:19:17 +0900 From: Michael Paquier To: gkokolatos@pm.me Cc: Justin Pryzby , pgsql-hackers@lists.postgresql.org, Rachel Heaton Subject: Re: Add LZ4 compression in pg_dump Message-ID: References: <165970942594.29780.15623018354659505573.pgcf@coridan.postgresql.org> <-pU80vtiyXMfSSpn4SWOR97t71MVmDOyHaJtvGsdEfroFsFUDdc-UaqD-8LMPMw2sy-7B2_IVnlrATfVvXwtv8n3kexLePZ7iWgiOnE4jRI=@pm.me> <20221120172611.GQ11463@telsasoft.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="uNlyzWoiGR9fZDn1" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --uNlyzWoiGR9fZDn1 Content-Type: multipart/mixed; boundary="om43PTiCxjHdQQQP" Content-Disposition: inline --om43PTiCxjHdQQQP Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Nov 28, 2022 at 04:32:43PM +0000, gkokolatos@pm.me wrote: > The focus of this version of this series is 0001 and 0002. >=20 > Admittedly 0001 could be presented in a separate thread though given its = size and > proximity to the topic, I present it here. I don't mind. This was a hole in meson.build, so nice catch! I have noticed a second defect with pg_verifybackup for all the commands, and applied both at the same time. > In an earlier review you spotted the similarity between pg_dump's and pg_= receivewal's > parsing of compression options. However there exists a substantial differ= ence in the > behaviour of the two programs; one treats the lack of support for the req= uested > algorithm as a fatal error, whereas the other does not. The existing func= tions in > common/compression.c do not account for the later. 0002 proposes an imple= mentation > for this. It's usefulness is shown in 0003. In what does it matter? The logic in compression.c provides an error when looking at a spec or validating it, but the caller is free to consume it as it wants because this is shared between the frontend and the backend, and that includes consuming it as a warning rather than a ahrd failure. If we don't want to issue an error and force non-compression if attempting to use a compression method not supported in pg_dump, that's fine by me as a historical behavior, but I don't see why these routines have any need to be split more as proposed in 0002. Saying that, I do agree that it would be nice to remove the duplication between the option parsing of pg_basebackup and pg_receivewal. Your patch is very close to that, actually, and it occured to me that if we move the check on "server-" and "client-" in pg_basebackup to be just before the integer-only check then we can consolidate the whole thing. Attached is an alternative that does not sacrifice the pluggability of the existing routines while allowing 0003~ to still use them (I don't really want to move around the checks on the supported build options now in parse_compress_specification(), that was hard enough to settle on this location). On top of that, pg_basebackup is able to cope with the case of --compress=3D0 already, enforcing "none" (BaseBackup could be simplified a bit more before StartLogStreamer). This refactoring shaves a little bit of code. > Please consider 0003-0005 as work in progress. They are differences from = v7 yet they > may contain unaddressed comments for now. Okay. -- Michael --om43PTiCxjHdQQQP Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v9-0001-Make-the-pg_receivewal-compression-parsing-functi.patch" Content-Transfer-Encoding: quoted-printable =46rom 6fb2aa609348ad7df6f9c12da60c07aa96243965 Mon Sep 17 00:00:00 2001 =46rom: Michael Paquier Date: Tue, 29 Nov 2022 15:17:27 +0900 Subject: [PATCH v9] Make the pg_receivewal compression parsing function com= mon Also and relax parsing errors in the helper functions and re-introduce thos= e as an independed function. As it is shown in the rest of the patch series, there is a lot of duplicati= on between pg_dump's parsing of compression options and pg_receivewal's. Now t= he core work is done in common. However pg_dump would not error out if the requested compression algorithm is not supported by the build, whereas other callers will error out. Also it seems a bit weird for only one of the parsi= ng functions for compressions to error out on missing support and that one to = not be the one responsible for identifying the compression algorithm. A new function is added to test the support of the algorithm allowing the u= ser to tune the behaviour. --- src/include/common/compression.h | 2 + src/common/compression.c | 63 +++++++++++++++++++++++++++ src/bin/pg_basebackup/pg_basebackup.c | 49 ++++----------------- src/bin/pg_basebackup/pg_receivewal.c | 61 -------------------------- 4 files changed, 73 insertions(+), 102 deletions(-) diff --git a/src/include/common/compression.h b/src/include/common/compress= ion.h index 5d680058ed..46855b1a3b 100644 --- a/src/include/common/compression.h +++ b/src/include/common/compression.h @@ -33,6 +33,8 @@ typedef struct pg_compress_specification char *parse_error; /* NULL if parsing was OK, else message */ } pg_compress_specification; =20 +extern void parse_compress_options(const char *option, char **algorithm, + char **detail); extern bool parse_compress_algorithm(char *name, pg_compress_algorithm *al= gorithm); extern const char *get_compress_algorithm_name(pg_compress_algorithm algor= ithm); =20 diff --git a/src/common/compression.c b/src/common/compression.c index df5b627834..5274ba5ba8 100644 --- a/src/common/compression.c +++ b/src/common/compression.c @@ -356,3 +356,66 @@ validate_compress_specification(pg_compress_specificat= ion *spec) =20 return NULL; } + +#ifdef FRONTEND + +/* + * Basic parsing of a value specified through a command-line option, commo= nly + * -Z/--compress. + * + * The parsing consists of a METHOD:DETAIL string fed later to + * parse_compress_specification(). This only extracts METHOD and DETAIL. + * If only an integer is found, the method is implied by the value specifi= ed. + */ +void +parse_compress_options(const char *option, char **algorithm, char **detail) +{ + char *sep; + char *endp; + long result; + + /* + * Check whether the compression specification consists of a bare integer. + * + * For backward-compatibility, assume "none" if the integer found is zero + * and "gzip" otherwise. + */ + result =3D strtol(option, &endp, 10); + if (*endp =3D=3D '\0') + { + if (result =3D=3D 0) + { + *algorithm =3D pstrdup("none"); + *detail =3D NULL; + } + else + { + *algorithm =3D pstrdup("gzip"); + *detail =3D pstrdup(option); + } + return; + } + + /* + * Check whether there is a compression detail following the algorithm + * name. + */ + sep =3D strchr(option, ':'); + if (sep =3D=3D NULL) + { + *algorithm =3D pstrdup(option); + *detail =3D NULL; + } + else + { + char *alg; + + alg =3D palloc((sep - option) + 1); + memcpy(alg, option, sep - option); + alg[sep - option] =3D '\0'; + + *algorithm =3D alg; + *detail =3D pstrdup(sep + 1); + } +} +#endif /* FRONTEND */ diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/= pg_basebackup.c index 22836ca01a..4f56c9f464 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -956,27 +956,13 @@ parse_max_rate(char *src) * at a later stage. */ static void -parse_compress_options(char *option, char **algorithm, char **detail, - CompressionLocation *locationres) +backup_parse_compress_options(char *option, char **algorithm, char **detai= l, + CompressionLocation *locationres) { - char *sep; - char *endp; - /* - * Check whether the compression specification consists of a bare integer. - * - * If so, for backward compatibility, assume gzip. + * Strip off any "client-" or "server-" prefix, calculating the + * location. */ - (void) strtol(option, &endp, 10); - if (*endp =3D=3D '\0') - { - *locationres =3D COMPRESS_LOCATION_UNSPECIFIED; - *algorithm =3D pstrdup("gzip"); - *detail =3D pstrdup(option); - return; - } - - /* Strip off any "client-" or "server-" prefix. */ if (strncmp(option, "server-", 7) =3D=3D 0) { *locationres =3D COMPRESS_LOCATION_SERVER; @@ -990,27 +976,8 @@ parse_compress_options(char *option, char **algorithm,= char **detail, else *locationres =3D COMPRESS_LOCATION_UNSPECIFIED; =20 - /* - * Check whether there is a compression detail following the algorithm - * name. - */ - sep =3D strchr(option, ':'); - if (sep =3D=3D NULL) - { - *algorithm =3D pstrdup(option); - *detail =3D NULL; - } - else - { - char *alg; - - alg =3D palloc((sep - option) + 1); - memcpy(alg, option, sep - option); - alg[sep - option] =3D '\0'; - - *algorithm =3D alg; - *detail =3D pstrdup(sep + 1); - } + /* fallback to the common parsing for the algorithm and detail */ + parse_compress_options(option, algorithm, detail); } =20 /* @@ -2411,8 +2378,8 @@ main(int argc, char **argv) compressloc =3D COMPRESS_LOCATION_UNSPECIFIED; break; case 'Z': - parse_compress_options(optarg, &compression_algorithm, - &compression_detail, &compressloc); + backup_parse_compress_options(optarg, &compression_algorithm, + &compression_detail, &compressloc); break; case 'c': if (pg_strcasecmp(optarg, "fast") =3D=3D 0) diff --git a/src/bin/pg_basebackup/pg_receivewal.c b/src/bin/pg_basebackup/= pg_receivewal.c index 63207ca025..c7a46b8a2a 100644 --- a/src/bin/pg_basebackup/pg_receivewal.c +++ b/src/bin/pg_basebackup/pg_receivewal.c @@ -57,8 +57,6 @@ static XLogRecPtr endpos =3D InvalidXLogRecPtr; =20 =20 static void usage(void); -static void parse_compress_options(char *option, char **algorithm, - char **detail); static DIR *get_destination_dir(char *dest_folder); static void close_destination_dir(DIR *dest_dir, char *dest_folder); static XLogRecPtr FindStreamingStart(uint32 *tli); @@ -109,65 +107,6 @@ usage(void) printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL); } =20 -/* - * Basic parsing of a value specified for -Z/--compress - * - * The parsing consists of a METHOD:DETAIL string fed later on to a more - * advanced routine in charge of proper validation checks. This only extr= acts - * METHOD and DETAIL. If only an integer is found, the method is implied = by - * the value specified. - */ -static void -parse_compress_options(char *option, char **algorithm, char **detail) -{ - char *sep; - char *endp; - long result; - - /* - * Check whether the compression specification consists of a bare integer. - * - * For backward-compatibility, assume "none" if the integer found is zero - * and "gzip" otherwise. - */ - result =3D strtol(option, &endp, 10); - if (*endp =3D=3D '\0') - { - if (result =3D=3D 0) - { - *algorithm =3D pstrdup("none"); - *detail =3D NULL; - } - else - { - *algorithm =3D pstrdup("gzip"); - *detail =3D pstrdup(option); - } - return; - } - - /* - * Check whether there is a compression detail following the algorithm - * name. - */ - sep =3D strchr(option, ':'); - if (sep =3D=3D NULL) - { - *algorithm =3D pstrdup(option); - *detail =3D NULL; - } - else - { - char *alg; - - alg =3D palloc((sep - option) + 1); - memcpy(alg, option, sep - option); - alg[sep - option] =3D '\0'; - - *algorithm =3D alg; - *detail =3D pstrdup(sep + 1); - } -} =20 /* * Check if the filename looks like a WAL file, letting caller know if this --=20 2.38.1 --om43PTiCxjHdQQQP-- --uNlyzWoiGR9fZDn1 Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEG72nH6vTowiyblFKnvQgOdbyQH0FAmOFpGUACgkQnvQgOdby QH3B4w//fMRlG/DIGz6b6W2pQOUaIhJ/tl0Q4q/2ku0rjyffu5IjacxR6JEExo9w kSLQvLkQm3wv04FNrosGW1sJ0ddKksC5hNHF4UwYyNjFhiE5Jf6RnyRUO2NkzH98 V1fx46HDXQlX848mzDvOaOLyX+AZS0hXn3ejVQIJkVuLGEeZBgoxtjoqZ8r1aTWv bqtfYl7NmA2Ttx2fxY0+gT56aD28eAp6JXgH8jVsccR5VK7TC0+0OuZo9J9wZwWl gQAzpGOkXnqhtYwo7PSbnbxv+n0tOAh0nh+qodvtO765+yPpeKGsWGNtr2Dbxw0g qpAYczFVobHCerGpykjOgXqkaG0rMY2Dvty4Ias7P97l18Jf8atcO96ooZDKD7cO DIv2AsUDkfqmPChbnIGJoSuGUSqP+a+xZJyiFdIAar0jzisQjgNBIcuAyU5LV8AM 4pnHwkn9Droro370yyLV7hKT2ObnYv+jlE6Ur17GvtegL6Qf9sMWQgG/14VKM56P hpxpew66WzIu0QXgK2fF+KseJUupXQjV6OmfDHaJXkbWdEM+N3s5J/9WOfo7fdAx y7r3UivO8E4E+TMYsSKRGdR6DMgF1mWtE+XPmtrOuihRsl9UPQfMmkoAryuo7SXu qpcxLPDgCK9uz3Oit5FIhVRmPn3URLcv7DghFaBXKQ3sKvx6Il8= =62t/ -----END PGP SIGNATURE----- --uNlyzWoiGR9fZDn1--