From 360e45485475100c12f27eb617e0ff802cb2bf40 Mon Sep 17 00:00:00 2001 From: Andrey Borodin Date: Sun, 30 Nov 2025 16:34:41 +0500 Subject: [PATCH v14 4/4] Improve multixact wraparound test 1. Replace dd and rm 2. Sprincle comments 3. Check that all multis are readable after wraparound --- .../test_slru/t/002_multixact_wraparound.pl | 54 +++++++++++++++---- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/src/test/modules/test_slru/t/002_multixact_wraparound.pl b/src/test/modules/test_slru/t/002_multixact_wraparound.pl index efaf902e5e3..c05d6280bfb 100644 --- a/src/test/modules/test_slru/t/002_multixact_wraparound.pl +++ b/src/test/modules/test_slru/t/002_multixact_wraparound.pl @@ -10,7 +10,7 @@ use PostgreSQL::Test::Utils; use Test::More; -my ($node, $result); +my $node; $node = PostgreSQL::Test::Cluster->new('mike'); $node->init; @@ -26,23 +26,55 @@ command_ok( $node_pgdata ], "set the cluster's next multitransaction to 0xFFFFFFF0"); -command_ok( - [ - 'dd', 'if=/dev/zero', "of=$node_pgdata/pg_multixact/offsets/FFFF", - 'bs=4', 'count=65536' - ], - "init SLRU file"); -command_ok([ 'rm', "$node_pgdata/pg_multixact/offsets/0000", ], - "drop old SLRU file"); +# Initialize SLRU file with zeros (65536 entries * 4 bytes = 262144 bytes) +my $slru_file = "$node_pgdata/pg_multixact/offsets/FFFF"; +open my $fh, ">", $slru_file + or die "could not open \"$slru_file\": $!"; +binmode $fh; +# Write 65536 entries of 4 bytes each (all zeros) +syswrite($fh, "\0" x 262144) == 262144 + or die "could not write to \"$slru_file\": $!"; +close $fh; + +# Remove old SLRU file if it exists +if (-f "$node_pgdata/pg_multixact/offsets/0000") +{ + unlink("$node_pgdata/pg_multixact/offsets/0000") + or die "could not unlink \"$node_pgdata/pg_multixact/offsets/0000\": $!"; +} $node->start; $node->safe_psql('postgres', q(CREATE EXTENSION test_slru)); -# Consume multixids to wrap around +# Consume multixids to wrap around. We start at 0xFFFFFFF0, so after +# creating 32 multixacts we should have wrapped around past FirstMultiXactId. +# Capture all multixact IDs to verify they're all readable after wraparound. +my @multixact_ids; foreach my $i (1 .. 32) { - $node->safe_psql('postgres', q{SELECT test_create_multixact();}); + my $multi = $node->safe_psql('postgres', q{SELECT test_create_multixact();}); + push @multixact_ids, $multi; +} + +# Verify that wraparound occurred (last_multi should be less than first_multi +# or very close to FirstMultiXactId) +my $first_multi = $multixact_ids[0]; +my $last_multi = $multixact_ids[-1]; +ok($last_multi < $first_multi || $last_multi < 0x10000, + "multixact wraparound occurred (first: $first_multi, last: $last_multi)"); + +# Verify that all multixacts created during wraparound are still readable +foreach my $i (0 .. $#multixact_ids) +{ + my $multi = $multixact_ids[$i]; + my $timed_out = 0; + $node->safe_psql( + 'postgres', + qq{SELECT test_read_multixact('$multi'::xid);}, + timeout => $PostgreSQL::Test::Utils::timeout_default, + timed_out => \$timed_out); + ok($timed_out == 0, "multixact $i (ID: $multi) is readable after wraparound"); } $node->stop; -- 2.51.2