From 2565a6b914e814063b1c0ed501c60fd8b5942f3d Mon Sep 17 00:00:00 2001 From: Maxim Orlov Date: Fri, 20 Jun 2025 17:20:59 +0300 Subject: [PATCH v1 1/2] Test case for BUG #18863 and BUG #18865 --- src/bin/pg_upgrade/meson.build | 1 + src/bin/pg_upgrade/t/007_mxwrap.pl | 111 +++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 src/bin/pg_upgrade/t/007_mxwrap.pl diff --git a/src/bin/pg_upgrade/meson.build b/src/bin/pg_upgrade/meson.build index ac992f0d14..aff3c5ddb4 100644 --- a/src/bin/pg_upgrade/meson.build +++ b/src/bin/pg_upgrade/meson.build @@ -47,6 +47,7 @@ tests += { 't/004_subscription.pl', 't/005_char_signedness.pl', 't/006_transfer_modes.pl', + 't/007_mxwrap.pl', ], 'test_kwargs': {'priority': 40}, # pg_upgrade tests are slow }, diff --git a/src/bin/pg_upgrade/t/007_mxwrap.pl b/src/bin/pg_upgrade/t/007_mxwrap.pl new file mode 100644 index 0000000000..2cba978c18 --- /dev/null +++ b/src/bin/pg_upgrade/t/007_mxwrap.pl @@ -0,0 +1,111 @@ +# +# Copyright (c) 2025, PostgreSQL Global Development Group +# +use strict; +use warnings FATAL => 'all'; + +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +sub print_controldata_info +{ + my $node = shift; + my ($stdout, $stderr) = run_command([ 'pg_controldata', $node->data_dir ]); + + foreach (split("\n", $stdout)) + { + if ($_ =~ /^Latest checkpoint's Next\s*(.*)$/mg or + $_ =~ /^Latest checkpoint's oldest\s*(.*)$/mg) + { + print $_."\n"; + } + } +} + +# 1) Create the new cluster - source_cluster +my $oldnode = PostgreSQL::Test::Cluster->new('main'); +$oldnode->init; + +# 2) Reset mxid to the limit +command_ok( + [ 'pg_resetwal', '-m', '4294967295,4294967295', $oldnode->data_dir ], + 'approaching the mxid limit'); +command_ok( + [ 'pg_resetwal', '-O', '4294967293', $oldnode->data_dir ], + 'approaching the mxoff limit'); + +# 3) Create files in pg_multixact offsets and members +my $offsets_seg = $oldnode->data_dir . '/pg_multixact/offsets/FFFF'; +open my $fh1, '>', $offsets_seg or BAIL_OUT($!); +binmode $fh1; +print $fh1 pack("x[262144]"); +close $fh1; + +my $members_seg = $oldnode->data_dir . '/pg_multixact/members/14078'; +open my $fh2, '>', $members_seg or BAIL_OUT($!); +binmode $fh2; +print $fh2 pack("x[262144]"); +close $fh2; + +# 4) Create the test table +$oldnode->start; +$oldnode->safe_psql('postgres', +qq( + CREATE TABLE test_table (id integer NOT NULL PRIMARY KEY, val text); + INSERT INTO test_table VALUES (1, 'a'); +)); + +# 5-9) Create a multitransaction +my $conn1 = $oldnode->background_psql('postgres'); +my $conn2 = $oldnode->background_psql('postgres'); + +$conn1->query_safe(qq( + BEGIN; + SELECT * FROM test_table WHERE id = 1 FOR SHARE; +)); +$conn2->query_safe(qq( + BEGIN; + SELECT * FROM test_table WHERE id = 1 FOR SHARE; +)); + +$conn1->query_safe(qq(COMMIT;)); +$conn2->query_safe(qq(COMMIT;)); + +$conn1->quit; +$conn2->quit; + +$oldnode->stop; + +# 10) Run pg_upgrade +my $newnode = PostgreSQL::Test::Cluster->new('new_node'); +$newnode->init; + +command_ok( + [ + 'pg_upgrade', '--no-sync', '-d', $oldnode->data_dir, + '-D', $newnode->data_dir, '-b', $oldnode->config_data('--bindir'), + '-B', $newnode->config_data('--bindir'), '-s', $newnode->host, + '-p', $oldnode->port, '-P', $newnode->port, + '--copy', + ], + 'run of pg_upgrade --check for new instance'); +ok(!-d $newnode->data_dir . "/pg_upgrade_output.d", + "pg_upgrade_output.d/ removed after pg_upgrade --check success"); + +print ">>> OLD NODE: \n"; +print_controldata_info($oldnode); + +print "\n>>> NEW NODE: \n"; +print_controldata_info($newnode); + +# just in case... +$newnode->start; +$oldnode->start; +is($newnode->safe_psql('postgres', qq(TABLE test_table;)), + $oldnode->safe_psql('postgres', qq(TABLE test_table;)), + 'check invariant'); +$newnode->stop; +$oldnode->stop; + +done_testing(); -- 2.43.0