From b3aaf8f4a79f3b66a9ca5e1a058f155f95937fef Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Wed, 21 Mar 2018 20:02:27 +0000 Subject: [PATCH v3 2/3] Allow users to change the WAL segment size with pg_resetwal. --- doc/src/sgml/ref/pg_resetwal.sgml | 24 +++++++++++++++++++++ src/bin/pg_resetwal/pg_resetwal.c | 45 ++++++++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 10 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 387ce51..506fdda 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -71,6 +71,7 @@ static MultiXactOffset set_mxoff = (MultiXactOffset) -1; static uint32 minXlogTli = 0; static XLogSegNo minXlogSegNo = 0; static int WalSegSz; +static bool walSegSzChanged = false; static void CheckDataVersion(void); static bool ReadControlFile(void); @@ -117,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) { @@ -275,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 == optarg || *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); @@ -357,6 +367,12 @@ main(int argc, char *argv[]) if (!ReadControlFile()) GuessControlValues(); + /* + * If no new WAL segment size was specified, use the control file value. + */ + if (WalSegSz == 0) + WalSegSz = ControlFile.xlog_seg_size; + if (log_fname != NULL) XLogFromFileName(log_fname, &minXlogTli, &minXlogSegNo, WalSegSz); @@ -423,6 +439,12 @@ main(int argc, char *argv[]) ControlFile.checkPointCopy.PrevTimeLineID = minXlogTli; } + if (WalSegSz != ControlFile.xlog_seg_size) + { + ControlFile.xlog_seg_size = WalSegSz; + walSegSzChanged = true; + } + if (minXlogSegNo > newXlogSegNo) newXlogSegNo = minXlogSegNo; @@ -593,14 +615,13 @@ ReadControlFile(void) } memcpy(&ControlFile, buffer, sizeof(ControlFile)); - WalSegSz = ControlFile.xlog_seg_size; - /* return false if WalSegSz is not valid */ - if (!IsValidWalSegSize(WalSegSz)) + /* return false if WAL segment size is not valid */ + if (!IsValidWalSegSize(ControlFile.xlog_seg_size)) { fprintf(stderr, _("%s: pg_control specifies invalid WAL segment size (%d bytes); proceed with caution \n"), - progname, WalSegSz); + progname, ControlFile.xlog_seg_size); return false; } @@ -679,7 +700,7 @@ GuessControlValues(void) ControlFile.blcksz = BLCKSZ; ControlFile.relseg_size = RELSEG_SIZE; ControlFile.xlog_blcksz = XLOG_BLCKSZ; - WalSegSz = ControlFile.xlog_seg_size = DEFAULT_XLOG_SEG_SIZE; + ControlFile.xlog_seg_size = DEFAULT_XLOG_SEG_SIZE; ControlFile.nameDataLen = NAMEDATALEN; ControlFile.indexMaxKeys = INDEX_MAX_KEYS; ControlFile.toast_max_chunk_size = TOAST_MAX_CHUNK_SIZE; @@ -844,6 +865,12 @@ PrintNewControlValues(void) printf(_("newestCommitTsXid: %u\n"), ControlFile.checkPointCopy.newestCommitTsXid); } + + if (walSegSzChanged) + { + printf(_("Bytes per WAL segment: %u\n"), + ControlFile.xlog_seg_size); + } } @@ -895,9 +922,6 @@ RewriteControlFile(void) ControlFile.max_prepared_xacts = 0; ControlFile.max_locks_per_xact = 64; - /* Now we can force the recorded xlog seg size to the right thing. */ - ControlFile.xlog_seg_size = WalSegSz; - /* Contents are protected with a CRC */ INIT_CRC32C(ControlFile.crc); COMP_CRC32C(ControlFile.crc, @@ -1033,7 +1057,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++; } @@ -1261,6 +1285,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