From: Alvaro Herrera Date: Thu, 10 Jun 2021 16:44:03 -0400 Subject: [PATCH 2/2] the test --- src/test/recovery/t/019_replslot_limit.pl | 73 ++++++++++++++++++++++- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/src/test/recovery/t/019_replslot_limit.pl b/src/test/recovery/t/019_replslot_limit.pl index 7094aa0704..fa47c915a5 100644 --- a/src/test/recovery/t/019_replslot_limit.pl +++ b/src/test/recovery/t/019_replslot_limit.pl @@ -11,7 +11,7 @@ use TestLib; use PostgresNode; use File::Path qw(rmtree); -use Test::More tests => 14; +use Test::More tests => 17; use Time::HiRes qw(usleep); $ENV{PGDATABASE} = 'postgres'; @@ -211,8 +211,8 @@ for (my $i = 0; $i < 10000; $i++) } ok($failed, 'check that replication has been broken'); -$node_primary->stop('immediate'); -$node_standby->stop('immediate'); +$node_primary->stop; +$node_standby->stop; my $node_primary2 = get_new_node('primary2'); $node_primary2->init(allows_streaming => 1); @@ -253,6 +253,73 @@ my @result = timeout => '60')); is($result[1], 'finished', 'check if checkpoint command is not blocked'); +$node_primary2->stop; +$node_standby->stop; + +# The next test depends on Perl's `kill`, which apparently is not +# portable to Windows. (It would be nice to use Test::More's `subtest`, +# but that's not in the ancient version we require.) +done_testing() if $TestLib::windows_os; + +# Get a slot terminated while the walsender is active +# We do this by sending SIGSTOP to the walreceiver. Skip this on Windows. +my $node_primary3 = get_new_node('primary3'); +$node_primary3->init(allows_streaming => 1, extra => ['--wal-segsize=1']); +$node_primary3->append_conf( + 'postgresql.conf', qq( + min_wal_size = 2MB + max_wal_size = 2MB + log_checkpoints = yes + max_slot_wal_keep_size = 1MB + )); +$node_primary3->start; +$node_primary3->safe_psql('postgres', + "SELECT pg_create_physical_replication_slot('rep3')"); +# Take backup +$backup_name = 'my_backup'; +$node_primary3->backup($backup_name); +# Create standby +my $node_standby3 = get_new_node('standby_3'); +$node_standby3->init_from_backup($node_primary3, $backup_name, + has_streaming => 1); +$node_standby3->append_conf('postgresql.conf', "primary_slot_name = 'rep3'"); +$node_standby3->start; +$node_primary3->wait_for_catchup($node_standby3->name, 'replay'); +my $pid = $node_standby3->safe_psql('postgres', + "SELECT pid FROM pg_stat_activity WHERE backend_type = 'walreceiver'"); +like($pid, qr/^[0-9]+$/, "have walreceiver pid $pid"); + +# freeze walreceiver. Slot will still be active, but it won't advance +kill 'STOP', $pid; +$logstart = get_log_size($node_primary3); +advance_wal($node_primary3, 2); + +my ($in, $out, $timer, $h); +$timer = IPC::Run::timeout(180); +$h = $node_primary3->background_psql('postgres', \$in, \$out, $timer); +$in .= qq{ +checkpoint; +}; +$h->pump_nb; +ok( find_in_log($node_primary3, + "to release replication slot"), + "walreceiver termination logged"); + +# Now let it continue to its demise +kill 'CONT', $pid; + +$node_primary3->poll_query_until('postgres', + "SELECT wal_status FROM pg_replication_slots WHERE slot_name = 'rep3'", + "lost") or die "timed out waiting for slot to be lost"; + +ok( find_in_log($node_primary3, + 'invalidating slot "rep3" because its restart_lsn'), + "slot invalidation logged"); + + +$node_primary3->stop; +$node_standby3->stop; + ##################################### # Advance WAL of $node by $n segments sub advance_wal -- 2.20.1 --6s6fi4xhi7ezemxn--