mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Fix a race in 035_standby_logical_decoding.pl
Buildfarm animals francolin and kestrel reported intermittent failures in 035_standby_logical_decoding.pl. The test checks that replaying DROP DATABASE on a standby terminates pg_recvlogical with the expected recovery-conflict message and removes the database's replication slots. To exercise this while pg_recvlogical is streaming, the test must wait for streaming to start before dropping the database on the primary. Previously, the test treated an active slot in pg_replication_slots as confirmation that pg_recvlogical was streaming. However, the slot can become active before pg_recvlogical has entered streaming mode. If DROP DATABASE is replayed during this window, pg_recvlogical can report a connection-closed error instead of the recovery-conflict message, causing the test to fail. Run pg_recvlogical with --verbose and wait for "streaming initiated" instead of checking whether the slot is active. This ensures that pg_recvlogical has entered streaming mode before the database is dropped on the primary. Back-patch to v16, where this test was introduced. Reported-by: Alexander Lakhin <exclusion@gmail.com> Author: Hayato Kuroda <kuroda.hayato@fujitsu.com> Reviewed-by: Alexander Lakhin <exclusion@gmail.com> Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> Reviewed-by: Fujii Masao <masao.fujii@gmail.com> Discussion: https://postgr.es/m/a50ff89b-fb2c-4912-8f89-50dd0bd0916b@gmail.com Backpatch-through: 16
This commit is contained in:
@@ -69,12 +69,13 @@ sub drop_logical_slots
|
||||
}
|
||||
|
||||
# Acquire one of the standby logical slots created by create_logical_slots().
|
||||
# In case wait is true we are waiting for an active pid on the 'activeslot' slot.
|
||||
# If wait is not true it means we are testing a known failure scenario.
|
||||
# If wait is true, wait for pg_recvlogical to enter streaming mode.
|
||||
# Otherwise, starting replication is expected to fail.
|
||||
sub make_slot_active
|
||||
{
|
||||
my ($node, $slot_prefix, $wait, $to_stdout, $to_stderr) = @_;
|
||||
my $slot_user_handle;
|
||||
my $timeout = IPC::Run::timeout($default_timeout);
|
||||
|
||||
my $active_slot = $slot_prefix . 'activeslot';
|
||||
$slot_user_handle = IPC::Run::start(
|
||||
@@ -85,20 +86,20 @@ sub make_slot_active
|
||||
'include-xids=0', '-o',
|
||||
'skip-empty-xacts=1', '--no-loop',
|
||||
'--start', '-f',
|
||||
'-'
|
||||
'-', '--verbose'
|
||||
],
|
||||
'>',
|
||||
$to_stdout,
|
||||
'2>',
|
||||
$to_stderr,
|
||||
IPC::Run::timeout($default_timeout));
|
||||
$timeout);
|
||||
|
||||
if ($wait)
|
||||
{
|
||||
# make sure activeslot is in use
|
||||
$node->poll_query_until('testdb',
|
||||
qq[SELECT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = '$active_slot' AND active_pid IS NOT NULL)]
|
||||
) or die "slot never became active";
|
||||
# Make sure that pg_recvlogical has entered streaming mode.
|
||||
pump_until($slot_user_handle, $timeout, $to_stderr,
|
||||
qr/streaming initiated/)
|
||||
or die "pg_recvlogical did not enter streaming mode";
|
||||
}
|
||||
return $slot_user_handle;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user