From e24a00603080d476087b8e327284d849f72d86a8 Mon Sep 17 00:00:00 2001 From: alterego655 <824662526@qq.com> Date: Wed, 12 Nov 2025 13:32:05 +0800 Subject: [PATCH v2] Use WAIT FOR LSN in PostgreSQL::Test::Cluster::wait_for_catchup() --- src/test/perl/PostgreSQL/Test/Cluster.pm | 32 +++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm index 35413f14019..41784553d4b 100644 --- a/src/test/perl/PostgreSQL/Test/Cluster.pm +++ b/src/test/perl/PostgreSQL/Test/Cluster.pm @@ -3328,6 +3328,9 @@ sub wait_for_catchup $mode = defined($mode) ? $mode : 'replay'; my %valid_modes = ('sent' => 1, 'write' => 1, 'flush' => 1, 'replay' => 1); + my $isrecovery = + $self->safe_psql('postgres', "SELECT pg_is_in_recovery()"); + chomp($isrecovery); croak "unknown mode $mode for 'wait_for_catchup', valid modes are " . join(', ', keys(%valid_modes)) unless exists($valid_modes{$mode}); @@ -3340,9 +3343,6 @@ sub wait_for_catchup } if (!defined($target_lsn)) { - my $isrecovery = - $self->safe_psql('postgres', "SELECT pg_is_in_recovery()"); - chomp($isrecovery); if ($isrecovery eq 't') { $target_lsn = $self->lsn('replay'); @@ -3360,6 +3360,32 @@ sub wait_for_catchup . $self->name . "\n"; # Before release 12 walreceiver just set the application name to # "walreceiver" + + # Use WAIT FOR LSN when appropriate + if (($mode eq 'replay') && ($isrecovery eq 't')) + { + my $timeout = $PostgreSQL::Test::Utils::timeout_default; + my $query = + qq[WAIT FOR LSN '${target_lsn}' WITH (timeout '${timeout}s', no_throw);]; + my $output = $self->safe_psql('postgres', $query); + chomp($output); + + if ($output ne 'success') + { + # Fetch additional detail for debugging purposes + $query = qq[SELECT * FROM pg_catalog.pg_stat_replication]; + my $details = $self->safe_psql('postgres', $query); + diag qq(WAIT FOR LSN failed with status: +${output}); + diag qq(Last pg_stat_replication contents: +${details}); + croak "failed waiting for catchup"; + } + print "done\n"; + return; + } + + # Polling for other modes or when WAIT FOR LSN is not applicable my $query = qq[SELECT '$target_lsn' <= ${mode}_lsn AND state = 'streaming' FROM pg_catalog.pg_stat_replication WHERE application_name IN ('$standby_name', 'walreceiver')]; -- 2.51.0