From e00b10052ec7fd42296401491875e209c6ae0489 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Tue, 13 Mar 2018 23:36:37 +0000 Subject: [PATCH v2 2/4] Prevent division-by-zero errors in pg_resetwal. Currently, if the control file data cannot be read, the WalSegSz will stay set to 0, which will cause division-by-zero errors later on. This change fixes this by ensuring that the WalSegSz variable is set when the control file data must be guessed. Even so, the control file may be corrupted and specify the WAL segment size to be 0 bytes. With this change, pg_resetwal defaults to a "guessed" segment size (the default WAL segment size) for this case. While the WalSegSz variable could presumably be removed entirely as part of this change, it is likely to prove useful in a follow-up change to allow changing the WAL segment size of a cluster with pg_resetwal. --- src/bin/pg_resetwal/pg_resetwal.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index a132cf2..a5df0fe 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 walSegSizeChanged = false; static void CheckDataVersion(void); static bool ReadControlFile(void); @@ -357,6 +358,19 @@ main(int argc, char *argv[]) if (!ReadControlFile()) GuessControlValues(); + /* + * Set WalSegSz. + * + * If the control file specifies the WAL segment size to be 0 bytes, guess + * that it should be the default WAL segment size. + */ + if (ControlFile.xlog_seg_size == 0) + { + ControlFile.xlog_seg_size = DEFAULT_XLOG_SEG_SIZE; + walSegSizeChanged = true; + } + WalSegSz = ControlFile.xlog_seg_size; + if (log_fname != NULL) XLogFromFileName(log_fname, &minXlogTli, &minXlogSegNo, WalSegSz); @@ -593,14 +607,12 @@ ReadControlFile(void) } memcpy(&ControlFile, buffer, sizeof(ControlFile)); - WalSegSz = ControlFile.xlog_seg_size; - /* return false if WalSegSz is not valid */ - if (!IsValidWalSegSize(WalSegSz)) + 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); guessed = true; } @@ -844,6 +856,12 @@ PrintNewControlValues(void) printf(_("newestCommitTsXid: %u\n"), ControlFile.checkPointCopy.newestCommitTsXid); } + + if (walSegSizeChanged) + { + printf(_("Bytes per WAL segment: %u\n"), + ControlFile.xlog_seg_size); + } } @@ -895,9 +913,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, -- 2.7.3.AMZN