From: Bertrand Drouvot Date: Tue, 9 Jun 2026 09:56:05 +0000 Subject: [PATCH v2 4/4] Add SQL-path test for read_local_xlog_page_guts() timeline race Extend the injection-point test in 035_standby_logical_decoding.pl to also cover the SQL-callable decoding path (pg_logical_slot_peek_changes) which exercises read_local_xlog_page_guts(). The test uses the same promotion and injection point as the walsender test: a background psql session is connected before promotion, then issues pg_logical_slot_peek_changes while startup is paused at the injection point. Author: Bertrand Drouvot Reviewed-by: Xuneng Zhou Reviewed-by: Hayato Kuroda Discussion: https://postgr.es/m/7daef094-abf3-4672-bc23-3df4763b16a3%40gmail.com --- .../recovery/t/035_standby_logical_decoding.pl | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) 100.0% src/test/recovery/t/ diff --git a/src/test/recovery/t/035_standby_logical_decoding.pl b/src/test/recovery/t/035_standby_logical_decoding.pl index 9b45c819241..6ec338ebf32 100644 --- a/src/test/recovery/t/035_standby_logical_decoding.pl +++ b/src/test/recovery/t/035_standby_logical_decoding.pl @@ -1068,11 +1068,13 @@ is($cascading_stdout, $expected, # timeline in this window. ################################################## -# Create a logical slot on the cascading standby for this test. +# Create logical slots on the cascading standby for this test. $node_cascading_standby->create_logical_slot_on_standby($node_standby, 'race_slot', 'testdb'); +$node_cascading_standby->create_logical_slot_on_standby($node_standby, + 'race_slot_sql', 'testdb'); -# Insert data so the slot has WAL to decode. +# Insert data so the slots have WAL to decode. $node_standby->safe_psql('testdb', qq[INSERT INTO decoding_test(x,y) SELECT s, s::text FROM generate_series(10,13) s;] ); @@ -1089,6 +1091,9 @@ COMMIT}; $node_standby->safe_psql('testdb', 'CREATE EXTENSION injection_points;'); $node_standby->wait_for_replay_catchup($node_cascading_standby); +# Open a background psql session BEFORE promotion for the SQL decoding test. +my $decode_session = $node_cascading_standby->background_psql('testdb'); + # Attach injection point to pause startup after WAL segment cleanup # but before RecoveryInProgress() flips to false. $node_cascading_standby->safe_psql('testdb', @@ -1130,6 +1135,14 @@ is($stdout2, $expected, 'got expected output from pg_recvlogical during promotion timeline switch' ); +# Verify SQL decoding (read_local_xlog_page_guts path) on the pre-connected +# session. +my $sql_out = $decode_session->query_safe( + "SELECT data FROM pg_logical_slot_peek_changes('race_slot_sql', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1')" +); +is($sql_out, $expected, + 'pg_logical_slot_peek_changes works during promotion timeline switch'); + # Resume promotion. $node_cascading_standby->safe_psql('testdb', "SELECT injection_points_wakeup('promotion-after-wal-segment-cleanup');"); -- 2.34.1 --Wctt8FE9hhxDGrBZ--