From b9a440ba4892f43e1f65c79c7b4da86d00053530 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Tue, 13 Mar 2018 23:37:28 +0000 Subject: [PATCH v2 3/4] Allow users to change the WAL segment size with pg_resetwal. Like the '--wal-segsize' option in initdb, the new 's' option accepts segment sizes in megabytes. This patch also fixes a small issue with the WAL starting address calculation that would cause the WAL byte position to go backwards in some cases. Note that some segment size changes will cause old WAL file names to be reused. The new documentation for '-s' contains a note warning of this side effect and how to avoid it. --- doc/src/sgml/ref/pg_resetwal.sgml | 24 ++++++++++++++++++++++++ src/bin/pg_resetwal/pg_resetwal.c | 25 ++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/ref/pg_resetwal.sgml b/doc/src/sgml/ref/pg_resetwal.sgml index 43b58a4..2bffb59 100644 --- a/doc/src/sgml/ref/pg_resetwal.sgml +++ b/doc/src/sgml/ref/pg_resetwal.sgml @@ -248,6 +248,30 @@ PostgreSQL documentation + wal_segment_size + + + Manually set the WAL segment size (in megabytes). + + + + The WAL segment size must be set to a power of 2 between 1 and 1024 (megabytes). + + + + + While pg_resetwal will set the WAL starting address + beyond the latest existing WAL segment file, some segment size changes + can cause previous WAL file names to be reused. It is recommended to use + together with to manually set the + WAL starting address if WAL file name overlap will cause problems with + your archiving strategy. + + + + + + xid diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index a5df0fe..604a8d2 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -118,7 +118,7 @@ main(int argc, char *argv[]) } - while ((c = getopt(argc, argv, "c:D:e:fl:m:no:O:x:")) != -1) + while ((c = getopt(argc, argv, "c:D:e:fl:m:no:O:x:s:")) != -1) { switch (c) { @@ -276,6 +276,15 @@ main(int argc, char *argv[]) log_fname = pg_strdup(optarg); break; + case 's': + WalSegSz = strtol(optarg, &endptr, 10) * 1024 * 1024; + if (*endptr != '\0' || !IsValidWalSegSize(WalSegSz)) + { + fprintf(stderr, _("%s: WAL segment size (-s) must be a power of 2 between 1 and 1024 (megabytes)\n"), progname); + exit(1); + } + break; + default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -363,13 +372,16 @@ main(int argc, char *argv[]) * * If the control file specifies the WAL segment size to be 0 bytes, guess * that it should be the default WAL segment size. + * + * If no new WAL segment size was set, use the control file value. */ if (ControlFile.xlog_seg_size == 0) { ControlFile.xlog_seg_size = DEFAULT_XLOG_SEG_SIZE; walSegSizeChanged = true; } - WalSegSz = ControlFile.xlog_seg_size; + if (WalSegSz == 0) + WalSegSz = ControlFile.xlog_seg_size; if (log_fname != NULL) XLogFromFileName(log_fname, &minXlogTli, &minXlogSegNo, WalSegSz); @@ -437,6 +449,12 @@ main(int argc, char *argv[]) ControlFile.checkPointCopy.PrevTimeLineID = minXlogTli; } + if (WalSegSz != ControlFile.xlog_seg_size) + { + ControlFile.xlog_seg_size = WalSegSz; + walSegSizeChanged = true; + } + if (minXlogSegNo > newXlogSegNo) newXlogSegNo = minXlogSegNo; @@ -1048,7 +1066,7 @@ FindEndOfXLOG(void) * are in virgin territory. */ xlogbytepos = newXlogSegNo * ControlFile.xlog_seg_size; - newXlogSegNo = (xlogbytepos + WalSegSz - 1) / WalSegSz; + newXlogSegNo = (xlogbytepos + ControlFile.xlog_seg_size - 1) / WalSegSz; newXlogSegNo++; } @@ -1276,6 +1294,7 @@ usage(void) printf(_(" -n no update, just show what would be done (for testing)\n")); printf(_(" -o OID set next OID\n")); printf(_(" -O OFFSET set next multitransaction offset\n")); + printf(_(" -s SIZE set WAL segment size (in megabytes)\n")); printf(_(" -V, --version output version information, then exit\n")); printf(_(" -x XID set next transaction ID\n")); printf(_(" -?, --help show this help, then exit\n")); -- 2.7.3.AMZN