On Wed, Feb 4, 2026 at 8:21 AM Fujii Masao <[email protected]> wrote:
> On Sun, Feb 1, 2026 at 6:33 AM Nikolay Samokhvalov <[email protected]> > wrote: > > > > Thank you for the review! > > > > Attached is v3 addressing your feedback: > > Thanks for updating the patch! > > With this patch, the test failed on my laptop as follows. > Could you please take a look and fix it? > > $ make -s check -C src/bin/pg_resetwal/ PROVE_TESTS="t/001*" > # +++ tap check in src/bin/pg_resetwal +++ > t/001_basic.pl .. 15/? # Tests were run but no plan was declared and > done_testing() was not seen. > # Looks like your test exited with 4 just after 82. > t/001_basic.pl .. Dubious, test returned 4 (wstat 1024, 0x400) > All 82 subtests passed > > Test Summary Report > ------------------- > t/001_basic.pl (Wstat: 1024 Tests: 82 Failed: 0) > Non-zero exit status: 4 > Parse errors: No plan found in TAP output > Files=1, Tests=82, 4 wallclock secs ( 0.03 usr 0.01 sys + 0.31 cusr > 0.65 csys = 1.00 CPU) > Result: FAIL > make: *** [check] Error 1 > v4 attached: rebased, fixed the failing test + added coverage for --dry-run.
From 93820badbbfe3453f85dda96af041937e83d833f Mon Sep 17 00:00:00 2001 From: Nikolay Samokhvalov <[email protected]> Date: Thu, 5 Feb 2026 05:17:26 +0000 Subject: [PATCH v4] Add --system-identifier option to pg_resetwal Add option to manually set the database system identifier. Useful for: - Making restored clusters distinct from originals - Cloning clusters for testing - Recovery attempts on corrupted clusters v4 changes: - Use "Database system identifier" label (Fujii Masao) - Use PRIu64 format - Fix test to use standard PG TAP functions (command_like, etc.) instead of non-existent run_command and fragile eval patterns - Add --dry-run output test for system identifier --- doc/src/sgml/ref/pg_resetwal.sgml | 23 +++++++++++++++++++++++ src/bin/pg_resetwal/pg_resetwal.c | 28 ++++++++++++++++++++++++++++ src/bin/pg_resetwal/t/001_basic.pl | 37 ++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/doc/src/sgml/ref/pg_resetwal.sgml b/doc/src/sgml/ref/pg_resetwal.sgml index 41f2b1d..8dc8f6c 100644 --- a/doc/src/sgml/ref/pg_resetwal.sgml +++ b/doc/src/sgml/ref/pg_resetwal.sgml @@ -359,6 +359,29 @@ PostgreSQL documentation </listitem> </varlistentry> + <varlistentry> + <term><option>--system-identifier=<replaceable class="parameter">system_identifier</replaceable></option></term> + <listitem> + <para> + Manually set the database system identifier. + </para> + + <para> + This option should only be used in recovery scenarios where you need + to make a restored cluster distinct from the original, or when cloning + a cluster for testing purposes. The value must be a positive 64-bit + integer and cannot be zero. + </para> + + <warning> + <para> + Changing the system identifier will break compatibility with existing + backups and standby servers. Use this option with extreme caution. + </para> + </warning> + </listitem> + </varlistentry> + <varlistentry> <term><option>--char-signedness=<replaceable class="parameter">option</replaceable></option></term> <listitem> diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index 85dc43d..5fe4800 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -97,6 +97,9 @@ static int wal_segsize_val; static bool char_signedness_given = false; static bool char_signedness_val; +static bool sysid_given = false; +static uint64 sysid_val; + static TimeLineID minXlogTli = 0; static XLogSegNo minXlogSegNo = 0; @@ -135,6 +138,7 @@ main(int argc, char *argv[]) {"next-transaction-id", required_argument, NULL, 'x'}, {"wal-segsize", required_argument, NULL, 1}, {"char-signedness", required_argument, NULL, 2}, + {"system-identifier", required_argument, NULL, 3}, {NULL, 0, NULL, 0} }; @@ -352,6 +356,20 @@ main(int argc, char *argv[]) break; } + case 3: + errno = 0; + sysid_val = strtou64(optarg, &endptr, 0); + if (endptr == optarg || *endptr != '\0' || errno != 0) + { + pg_log_error("invalid argument for option %s", "--system-identifier"); + pg_log_error_hint("Try \"%s --help\" for more information.", progname); + exit(1); + } + if (sysid_val == 0) + pg_fatal("system identifier must not be 0"); + sysid_given = true; + break; + default: /* getopt_long already emitted a complaint */ pg_log_error_hint("Try \"%s --help\" for more information.", progname); @@ -510,6 +528,9 @@ main(int argc, char *argv[]) if (char_signedness_given) ControlFile.default_char_signedness = char_signedness_val; + if (sysid_given) + ControlFile.system_identifier = sysid_val; + if (minXlogSegNo > newXlogSegNo) newXlogSegNo = minXlogSegNo; @@ -894,6 +915,12 @@ PrintNewControlValues(void) printf(_("Bytes per WAL segment: %u\n"), ControlFile.xlog_seg_size); } + + if (sysid_given) + { + printf(_("Database system identifier: %" PRIu64 "\n"), + ControlFile.system_identifier); + } } @@ -1236,6 +1263,7 @@ usage(void) printf(_(" -O, --multixact-offset=OFFSET set next multitransaction offset\n")); printf(_(" -u, --oldest-transaction-id=XID set oldest transaction ID\n")); printf(_(" -x, --next-transaction-id=XID set next transaction ID\n")); + printf(_(" --system-identifier=SYSID set database system identifier\n")); printf(_(" --char-signedness=OPTION set char signedness to \"signed\" or \"unsigned\"\n")); printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n")); diff --git a/src/bin/pg_resetwal/t/001_basic.pl b/src/bin/pg_resetwal/t/001_basic.pl index d686584..ea889b3 100644 --- a/src/bin/pg_resetwal/t/001_basic.pl +++ b/src/bin/pg_resetwal/t/001_basic.pl @@ -194,6 +194,42 @@ command_fails_like( qr/error: invalid argument for option --char-signedness/, 'fails with incorrect --char-signedness option'); +# --system-identifier +command_fails_like( + [ 'pg_resetwal', '--system-identifier' => 'foo', $node->data_dir ], + qr/error: invalid argument for option --system-identifier/, + 'fails with incorrect --system-identifier option'); +command_fails_like( + [ 'pg_resetwal', '--system-identifier' => '0', $node->data_dir ], + qr/system identifier must not be 0/, + 'fails with zero system identifier'); + +# Test actual system identifier change with force flag +$node->stop; +my $new_sysid = '7654321098765432109'; +command_ok( + [ 'pg_resetwal', '-f', '--system-identifier' => $new_sysid, $node->data_dir ], + 'pg_resetwal --system-identifier with force flag succeeds'); + +# Verify the change using pg_controldata (handles uint64 correctly) +command_like( + [ 'pg_controldata', $node->data_dir ], + qr/Database system identifier:\s+\Q$new_sysid/, + 'system identifier was changed correctly'); + +# Test that the server works normally after system identifier change +$node->start; +is($node->safe_psql("postgres", "SELECT 1;"), + 1, 'server running and working after system identifier change'); + +$node->stop; + +# Verify --dry-run output shows the new system identifier +command_like( + [ 'pg_resetwal', '--dry-run', '-f', '--system-identifier' => $new_sysid, $node->data_dir ], + qr/Database system identifier:\s+\Q$new_sysid/, + 'dry-run output shows new system identifier'); + # run with control override options my $out = (run_command([ 'pg_resetwal', '--dry-run', $node->data_dir ]))[0];
