1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

Avoid spurious failures in the login event trigger recovery test

Buildfarm member skink reported failures in
053_standby_login_event_trigger.pl. The checks that dathasloginevt was
cleared on the primary and that the cleared flag reached the standby
both found the flag still set.

The test assumed that the first login after dropping the trigger would
clear the flag. However, EventTriggerOnLogin() acquires the database
lock conditionally to avoid delaying connections for this cleanup.
Concurrent connection startup, including that of an autovacuum worker,
can hold a conflicting lock and cause the cleanup to be skipped. The
standby correctly retained the flag because it had not been cleared
on the primary.

Fix this by using poll_query_until() to retry with fresh connections
to the test database until the flag is cleared, giving the login cleanup
repeated opportunities to acquire the lock.

Backpatch to v17, like commit bec61f5935, which added this test.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Author: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/09561429-50c1-4d06-a262-300c7a845175@gmail.com
Backpatch-through: 17
This commit is contained in:
Fujii Masao
2026-10-17 00:18:39 +09:00
parent df1be4ddc8
commit 80cf511236

View File

@@ -97,21 +97,15 @@ unlike(
qr/cannot acquire lock mode AccessExclusiveLock/,
'no AccessExclusiveLock FATAL on standby login');
# Finally exercise the primary-side cleanup that the standby is meant
# to defer to. Opening a fresh session against regress_login_evt on
# the primary enters EventTriggerOnLogin()'s cleanup branch with the
# trigger list empty; AccessExclusiveLock is allowed outside recovery,
# so the flag is cleared in place. The in-place update emits a
# XLOG_HEAP_INPLACE record but does not assign an xid or write a
# commit record, so the WAL is not auto-flushed -- force a flush via
# pg_switch_wal() so the record reaches the standby.
$primary->safe_psql('regress_login_evt', 'SELECT 1');
is( $primary->safe_psql(
'postgres',
"SELECT dathasloginevt FROM pg_database WHERE datname = 'regress_login_evt'"
),
'f',
'primary clears dathasloginevt on next login after DROP');
# Cleanup's conditional database lock can fail, so retry fresh logins.
# The in-place update emits a XLOG_HEAP_INPLACE record but does not assign
# an xid or write a commit record, so the WAL is not auto-flushed -- force
# a flush via pg_switch_wal() so the record reaches the standby.
ok( $primary->poll_query_until(
'regress_login_evt',
"SELECT dathasloginevt FROM pg_database WHERE datname = 'regress_login_evt'",
'f'),
'primary eventually clears dathasloginevt after DROP');
$primary->safe_psql('postgres', 'SELECT pg_switch_wal()');
$primary->wait_for_replay_catchup($standby);