From 794d7b6a45d13fc92399cb27f235e48143871eae Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 7 Oct 2026 21:31:47 +0900 Subject: [PATCH v2] Fix crash-restart race in 041_checkpoint_at_promote.pl The buildfarm member bushmaster reported failures in the final test query in 041_checkpoint_at_promote.pl with "the database system is in recovery mode". After killing a backend to trigger crash recovery, the test should wait for the postmaster to terminate the remaining server processes and restart the server, then wait for recovery to finish and connections to be accepted before running the final query. Previously, the test assumed that the killed backend's connection closing meant the postmaster had noticed the crash and begun restarting. However, the connection can close before the postmaster notices the crash. The subsequent connection check can then succeed before recovery starts, causing the test to mistake this for recovery having completed. The final query could then run during recovery and fail. Fix this by waiting for the postmaster to log that all server processes have terminated and it is reinitializing before checking that connections are accepted again. This ensures that the postmaster has noticed the crash and begun restarting before the test waits for recovery to finish. Backpatch to v17, where this test was introduced. Reported-by: Alexander Lakhin Author: Fujii Masao Discussion: https://postgr.es/m/e7abd282-655d-495e-94c9-e38a58917ebf@gmail.com Backpatch-through: 17 --- src/test/recovery/t/041_checkpoint_at_promote.pl | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/test/recovery/t/041_checkpoint_at_promote.pl b/src/test/recovery/t/041_checkpoint_at_promote.pl index d0783fef9ae..82173b9d86e 100644 --- a/src/test/recovery/t/041_checkpoint_at_promote.pl +++ b/src/test/recovery/t/041_checkpoint_at_promote.pl @@ -142,10 +142,13 @@ chomp($pid); $killme_stdout = ''; $killme_stderr = ''; +# Record the log position before triggering crash recovery. +my $crash_logstart = -s $node_standby->logfile; + my $ret = PostgreSQL::Test::Utils::system_log('pg_ctl', 'kill', 'KILL', $pid); is($ret, 0, 'killed process with KILL'); -# Wait until the server restarts, finish consuming output. +# Finish consuming output from the killed backend. $killme_stdin .= q[ SELECT 1; ]; @@ -158,8 +161,15 @@ ok( pump_until( "psql query died successfully after SIGKILL"); $killme->finish; -# Wait till server finishes restarting. -$node_standby->poll_query_until('postgres', undef, ''); +# Wait until the postmaster has noticed the crash and begun restarting. +# The killed backend's connection can fail before this happens. +$node_standby->wait_for_log( + qr/all server processes terminated; reinitializing/, + $crash_logstart); + +# Wait until recovery finishes and connections are accepted. +is($node_standby->poll_query_until('postgres', undef, ''), + 1, 'reconnected after SIGKILL'); # After recovery, the server should be able to start. my $stdout; -- 2.56.0