]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
pg_resetwal: do not allow zero next multixact offset
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 27 Jul 2026 12:29:51 +0000 (15:29 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 27 Jul 2026 12:29:51 +0000 (15:29 +0300)
Offset 0 is the "invalid" marker in pg_multixact/offsets since offsets
went 64-bit and the allocator stopped skipping it. pg_resetwal could
still produce it via -O 0 or guessed control values, breaking the first
multixact created after the reset ("MultiXact n has invalid offset",
and vacuum of the affected table fails from then on). Reject -O 0 like
-m and -o already do, and guess 1 like initdb does.

Author: Zsolt Parragi <zsolt.parragi@percona.com>
Discussion: https://www.postgresql.org/message-id/CAN4CZFNoO6MUkg526TmA=mC_RjY2gp4VKCnvK6y12v3ppOkhJA@mail.gmail.com
Backpatch-through: 19

src/bin/pg_resetwal/pg_resetwal.c
src/bin/pg_resetwal/t/001_basic.pl

index d072e7c2ea471c1fb81e31155736dc16dea67ff4..1542a56ca4b1fb44698d0c83c105e57edc6cdd4a 100644 (file)
@@ -303,6 +303,10 @@ main(int argc, char *argv[])
                                        pg_log_error_hint("Try \"%s --help\" for more information.", progname);
                                        exit(1);
                                }
+
+                               /* offset 0 means "invalid" in pg_multixact/offsets */
+                               if (next_mxoff_val == 0)
+                                       pg_fatal("next multitransaction offset (-O) must not be 0");
                                next_mxoff_given = true;
                                break;
 
@@ -700,7 +704,7 @@ GuessControlValues(void)
                FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId);
        ControlFile.checkPointCopy.nextOid = FirstGenbkiObjectId;
        ControlFile.checkPointCopy.nextMulti = FirstMultiXactId;
-       ControlFile.checkPointCopy.nextMultiOffset = 0;
+       ControlFile.checkPointCopy.nextMultiOffset = 1;
        ControlFile.checkPointCopy.oldestXid = FirstNormalTransactionId;
        ControlFile.checkPointCopy.oldestXidDB = InvalidOid;
        ControlFile.checkPointCopy.oldestMulti = FirstMultiXactId;
index d686584eb96744f0a9865451aafd6dbf4df4d5e7..cff0b6423f390253bd015133c6e46d96b5efd505 100644 (file)
@@ -145,6 +145,10 @@ command_fails_like(
        [ 'pg_resetwal', '-O' => '-1', $node->data_dir ],
        qr/error: invalid argument for option -O/,
        'fails with -O value -1');
+command_fails_like(
+       [ 'pg_resetwal', '-O' => '0', $node->data_dir ],
+       qr/must not be 0/,
+       'fails with -O value 0');
 # --wal-segsize
 command_fails_like(
        [ 'pg_resetwal', '--wal-segsize' => 'foo', $node->data_dir ],