diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index e9dcb5a6d89..a18906756b0 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -69,8 +69,10 @@ static TransactionId set_xid = 0; static TransactionId set_oldest_commit_ts_xid = 0; static TransactionId set_newest_commit_ts_xid = 0; static Oid set_oid = 0; +static bool mxid_given = false; static MultiXactId set_mxid = 0; -static MultiXactOffset set_mxoff = (MultiXactOffset) -1; +static bool mxoff_given = false; +static MultiXactOffset set_mxoff = 0; static TimeLineID minXlogTli = 0; static XLogSegNo minXlogSegNo = 0; static int WalSegSz; @@ -115,6 +117,7 @@ main(int argc, char *argv[]) MultiXactId set_oldestmxid = 0; char *endptr; char *endptr2; + int64 tmpi64; char *DataDir = NULL; char *log_fname = NULL; int fd; @@ -251,8 +254,6 @@ main(int argc, char *argv[]) pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1); } - if (set_mxid == 0) - pg_fatal("multitransaction ID (-m) must not be 0"); /* * XXX It'd be nice to have more sanity checks here, e.g. so @@ -260,19 +261,23 @@ main(int argc, char *argv[]) */ if (set_oldestmxid == 0) pg_fatal("oldest multitransaction ID (-m) must not be 0"); + mxid_given = true; break; case 'O': errno = 0; - set_mxoff = strtoul(optarg, &endptr, 0); + tmpi64 = strtoi64(optarg, &endptr, 0); if (endptr == optarg || *endptr != '\0' || errno != 0) { pg_log_error("invalid argument for option %s", "-O"); pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1); } - if (set_mxoff == -1) - pg_fatal("multitransaction offset (-O) must not be -1"); + if (tmpi64 < 0 || tmpi64 > (int64) MaxMultiXactOffset) + pg_fatal("multitransaction offset (-O) must be between 0 and %u", MaxMultiXactOffset); + + set_mxoff = (MultiXactOffset) tmpi64; + mxoff_given = true; break; case 'l': @@ -434,7 +439,7 @@ main(int argc, char *argv[]) if (set_oid != 0) ControlFile.checkPointCopy.nextOid = set_oid; - if (set_mxid != 0) + if (mxid_given) { ControlFile.checkPointCopy.nextMulti = set_mxid; @@ -444,7 +449,7 @@ main(int argc, char *argv[]) ControlFile.checkPointCopy.oldestMultiDB = InvalidOid; } - if (set_mxoff != -1) + if (mxoff_given) ControlFile.checkPointCopy.nextMultiOffset = set_mxoff; if (minXlogTli > ControlFile.checkPointCopy.ThisTimeLineID) @@ -797,7 +802,7 @@ PrintNewControlValues(void) newXlogSegNo, WalSegSz); printf(_("First log segment after reset: %s\n"), fname); - if (set_mxid != 0) + if (mxid_given) { printf(_("NextMultiXactId: %u\n"), ControlFile.checkPointCopy.nextMulti); @@ -807,7 +812,7 @@ PrintNewControlValues(void) ControlFile.checkPointCopy.oldestMultiDB); } - if (set_mxoff != -1) + if (mxoff_given) { printf(_("NextMultiOffset: %u\n"), ControlFile.checkPointCopy.nextMultiOffset); diff --git a/src/bin/pg_resetwal/t/001_basic.pl b/src/bin/pg_resetwal/t/001_basic.pl index 9829e48106e..ae260bbc1c1 100644 --- a/src/bin/pg_resetwal/t/001_basic.pl +++ b/src/bin/pg_resetwal/t/001_basic.pl @@ -118,10 +118,12 @@ command_fails_like( [ 'pg_resetwal', '-m', '10,bar', $node->data_dir ], qr/error: invalid argument for option -m/, 'fails with incorrect -m option part 2'); -command_fails_like( - [ 'pg_resetwal', '-m', '0,10', $node->data_dir ], - qr/must not be 0/, - 'fails with -m value 0 part 1'); + +# This used to be forbidden, but nextMulti can legitimately be 0 after +# wraparound, so we now accept it in pg_resetwal too. +command_ok([ 'pg_resetwal', '-m', '0,10', $node->data_dir ], + 'succeeds with -m value 0 part 1'); + command_fails_like( [ 'pg_resetwal', '-m', '10,0', $node->data_dir ], qr/must not be 0/, @@ -142,7 +144,7 @@ command_fails_like( 'fails with incorrect -O option'); command_fails_like( [ 'pg_resetwal', '-O', '-1', $node->data_dir ], - qr/must not be -1/, + qr/must be between 0 and 4294967295/, 'fails with -O value -1'); # --wal-segsize command_fails_like(