From c0bb04d4626da331813603627c17c5f30075713a Mon Sep 17 00:00:00 2001 From: Rushabh Lathia Date: Tue, 19 Nov 2019 14:42:39 +0530 Subject: [PATCH] Make checksum optional in pg_basebackup. --- src/backend/replication/basebackup.c | 50 ++++++++++++++++++++++++++-------- src/backend/replication/repl_gram.y | 6 ++++ src/backend/replication/repl_scanner.l | 1 + src/bin/pg_basebackup/pg_basebackup.c | 12 ++++++-- 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index 273f837..a98d949 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -132,6 +132,9 @@ static long long int total_checksum_failures; /* Do not verify checksums. */ static bool noverify_checksums = false; +/* Add file entry in to manifest with checksums. */ +static bool manifest_with_checksums = false; + /* * The contents of these directories are removed or recreated during server * start so they are not included in backups. The directories themselves are @@ -674,6 +677,7 @@ parse_basebackup_options(List *options, basebackup_options *opt) bool o_maxrate = false; bool o_tablespace_map = false; bool o_noverify_checksums = false; + bool o_manifest_with_checksums = false; MemSet(opt, 0, sizeof(*opt)); foreach(lopt, options) @@ -762,6 +766,16 @@ parse_basebackup_options(List *options, basebackup_options *opt) noverify_checksums = true; o_noverify_checksums = true; } + else if (strcmp(defel->defname, "manifest_with_checksums") == 0) + { + if (o_manifest_with_checksums) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("duplicate option \"%s\"", defel->defname))); + manifest_with_checksums = true; + o_manifest_with_checksums = true; + } + else elog(ERROR, "option \"%s\" not recognized", defel->defname); @@ -930,15 +944,18 @@ AddFileToManifest(StringInfo manifest, const char *tsoid, pg_strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S %Z", tm); /* Convert checksum to hexadecimal. */ - shatextlen = - hex_encode((char *) shabuf, PG_SHA256_DIGEST_LENGTH, shatextbuf); - Assert(shatextlen + 1 == sizeof(shatextbuf)); - shatextbuf[shatextlen] = '\0'; + if (manifest_with_checksums) + { + shatextlen = + hex_encode((char *) shabuf, PG_SHA256_DIGEST_LENGTH, shatextbuf); + Assert(shatextlen + 1 == sizeof(shatextbuf)); + shatextbuf[shatextlen] = '\0'; + } /* Add to manifest. */ appendStringInfo(manifest, "File\t%s\t%zu\t%s\t%s\n", escaped_filename == NULL ? filename : escaped_filename, - size, timebuf, shatextbuf); + size, timebuf, manifest_with_checksums ? shatextbuf : "-"); /* Avoid leaking memory. */ if (escaped_filename != NULL) @@ -1100,7 +1117,8 @@ sendFileWithContent(const char *filename, const char *content, pg_sha256_ctx sha256_ctx; uint8 shabuf[PG_SHA256_DIGEST_LENGTH]; - pg_sha256_init(&sha256_ctx); + if (manifest_with_checksums) + pg_sha256_init(&sha256_ctx); len = strlen(content); @@ -1134,8 +1152,12 @@ sendFileWithContent(const char *filename, const char *content, pq_putmessage('d', buf, pad); } - pg_sha256_update(&sha256_ctx, (uint8 *) content, len); - pg_sha256_final(&sha256_ctx, shabuf); + if (manifest_with_checksums) + { + pg_sha256_update(&sha256_ctx, (uint8 *) content, len); + pg_sha256_final(&sha256_ctx, shabuf); + } + AddFileToManifest(manifest, NULL, filename, len, statbuf.st_mtime, shabuf); } @@ -1571,7 +1593,8 @@ sendFile(const char *readfilename, const char *tarfilename, pg_sha256_ctx sha256_ctx; uint8 shabuf[PG_SHA256_DIGEST_LENGTH]; - pg_sha256_init(&sha256_ctx); + if (manifest_with_checksums) + pg_sha256_init(&sha256_ctx); fp = AllocateFile(readfilename, "rb"); if (fp == NULL) @@ -1742,7 +1765,8 @@ sendFile(const char *readfilename, const char *tarfilename, (errmsg("base backup could not send data, aborting backup"))); /* Also feed it to the checksum machinery. */ - pg_sha256_update(&sha256_ctx, (uint8 *) buf, cnt); + if (manifest_with_checksums) + pg_sha256_update(&sha256_ctx, (uint8 *) buf, cnt); len += cnt; throttle(cnt); @@ -1768,7 +1792,8 @@ sendFile(const char *readfilename, const char *tarfilename, { cnt = Min(sizeof(buf), statbuf->st_size - len); pq_putmessage('d', buf, cnt); - pg_sha256_update(&sha256_ctx, (uint8 *) buf, cnt); + if (manifest_with_checksums) + pg_sha256_update(&sha256_ctx, (uint8 *) buf, cnt); len += cnt; throttle(cnt); } @@ -1801,7 +1826,8 @@ sendFile(const char *readfilename, const char *tarfilename, total_checksum_failures += checksum_failures; - pg_sha256_final(&sha256_ctx, shabuf); + if (manifest_with_checksums) + pg_sha256_final(&sha256_ctx, shabuf); AddFileToManifest(manifest, tsoid, tarfilename, statbuf->st_size, statbuf->st_mtime, shabuf); diff --git a/src/backend/replication/repl_gram.y b/src/backend/replication/repl_gram.y index c4e11cc..542a3f7 100644 --- a/src/backend/replication/repl_gram.y +++ b/src/backend/replication/repl_gram.y @@ -87,6 +87,7 @@ static SQLCmd *make_sqlcmd(void); %token K_EXPORT_SNAPSHOT %token K_NOEXPORT_SNAPSHOT %token K_USE_SNAPSHOT +%token K_MANIFEST_WITH_CHECKSUMS %type command %type base_backup start_replication start_logical_replication @@ -214,6 +215,11 @@ base_backup_opt: $$ = makeDefElem("noverify_checksums", (Node *)makeInteger(true), -1); } + | K_MANIFEST_WITH_CHECKSUMS + { + $$ = makeDefElem("manifest_with_checksums", + (Node *)makeInteger(true), -1); + } ; create_replication_slot: diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l index 380faeb..4f92bc1 100644 --- a/src/backend/replication/repl_scanner.l +++ b/src/backend/replication/repl_scanner.l @@ -107,6 +107,7 @@ EXPORT_SNAPSHOT { return K_EXPORT_SNAPSHOT; } NOEXPORT_SNAPSHOT { return K_NOEXPORT_SNAPSHOT; } USE_SNAPSHOT { return K_USE_SNAPSHOT; } WAIT { return K_WAIT; } +MANIFEST_WITH_CHECKSUMS { return K_MANIFEST_WITH_CHECKSUMS; } "," { return ','; } ";" { return ';'; } diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index 508e4a6..f4f8ffe 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -141,6 +141,7 @@ static bool temp_replication_slot = true; static bool create_slot = false; static bool no_slot = false; static bool verify_checksums = true; +static bool manifest_with_checksums = false; static bool success = false; static bool made_new_pgdata = false; @@ -398,6 +399,8 @@ usage(void) printf(_(" --no-slot prevent creation of temporary replication slot\n")); printf(_(" --no-verify-checksums\n" " do not verify checksums\n")); + printf(_(" --manifest-with-checksums\n" + " do calculate checksums for manifest files\n")); printf(_(" -?, --help show this help, then exit\n")); printf(_("\nConnection options:\n")); printf(_(" -d, --dbname=CONNSTR connection string\n")); @@ -1821,7 +1824,7 @@ BaseBackup(void) } basebkp = - psprintf("BASE_BACKUP LABEL '%s' %s %s %s %s %s %s %s", + psprintf("BASE_BACKUP LABEL '%s' %s %s %s %s %s %s %s %s", escaped_label, showprogress ? "PROGRESS" : "", includewal == FETCH_WAL ? "WAL" : "", @@ -1829,7 +1832,8 @@ BaseBackup(void) includewal == NO_WAL ? "" : "NOWAIT", maxrate_clause ? maxrate_clause : "", format == 't' ? "TABLESPACE_MAP" : "", - verify_checksums ? "" : "NOVERIFY_CHECKSUMS"); + verify_checksums ? "" : "NOVERIFY_CHECKSUMS", + manifest_with_checksums ? "MANIFEST_WITH_CHECKSUMS" : ""); if (PQsendQuery(conn, basebkp) == 0) { @@ -2162,6 +2166,7 @@ main(int argc, char **argv) {"waldir", required_argument, NULL, 1}, {"no-slot", no_argument, NULL, 2}, {"no-verify-checksums", no_argument, NULL, 3}, + {"manifest-with-checksums", no_argument, NULL, 4}, {NULL, 0, NULL, 0} }; int c; @@ -2330,6 +2335,9 @@ main(int argc, char **argv) case 3: verify_checksums = false; break; + case 4: + manifest_with_checksums = true; + break; default: /* -- 1.8.3.1