From 8fabcb973649faeacea95b96c4b1bc2c619dbbc6 Mon Sep 17 00:00:00 2001
From: Zhijie Hou <houzj.fnst@fujitsu.com>
Date: Thu, 29 Jan 2026 15:13:07 +0800
Subject: [PATCH v7 2/2] Add a taptest

---
 .../t/040_standby_failover_slots_sync.pl      | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/src/test/recovery/t/040_standby_failover_slots_sync.pl b/src/test/recovery/t/040_standby_failover_slots_sync.pl
index 47d64d05ad1..b4bfe4878cb 100644
--- a/src/test/recovery/t/040_standby_failover_slots_sync.pl
+++ b/src/test/recovery/t/040_standby_failover_slots_sync.pl
@@ -1102,4 +1102,71 @@ $standby2->wait_for_log(
 
 $h->quit;
 
+##################################################
+# Test that when physical replication lags behind logical replication,
+# pg_sync_replication_slots() on the standby skips and retries until the slot
+# becomes sync-ready when physical replication catches up. Also verify that
+# slotsync skip statistics are correctly updated when the slotsync operation is
+# skipped.
+##################################################
+
+# Disable the subscription in previous test
+$subscriber1->safe_psql('postgres', "ALTER SUBSCRIPTION regress_mysub1 DISABLE");
+
+# Remove the standby from the synchronized_standby_slots and reduce the maximum
+# walsender number.
+$primary->append_conf('postgresql.conf', "max_wal_senders = 1");
+$primary->restart;
+
+# Stop the standby and initiate a new replication connection to occupy a
+# walsender slot, blocking physical replication.
+$standby2->stop;
+my $repl = $primary->background_psql('postgres', on_error_stop => 0,
+	replication => 'database');
+
+# Advance the wal position
+$primary->safe_psql('postgres', "INSERT INTO push_wal VALUES(1);");
+
+# Create a failover slot whose confirmed flush LSN is ahead of the physical
+# slot.
+$primary->psql('postgres',
+	q{SELECT pg_create_logical_replication_slot('lsub2_slot', 'test_decoding', false, false, true);}
+);
+
+$standby2->start;
+
+# Attempt to synchronize slots using API. The API will continue retrying
+# synchronization until the standby catches up.
+# The API will not return until this happens, to be able to make
+# further calls, call the API in a background process.
+$h = $standby2->background_psql('postgres', on_error_stop => 0);
+
+$log_offset = -s $standby2->logfile;
+
+$h->query_until(qr/start/, q(
+	\echo start
+	SELECT pg_sync_replication_slots();
+	));
+
+# Confirm that slot synchronization is skipped because physical replication is
+# lagging behind logical replication.
+$standby2->wait_for_log(
+	qr/skipping slot synchronization because the received slot sync LSN .* for slot \"lsub2_slot\" is ahead of the standby position/, $log_offset);
+
+# Confirm that the slotsync skip reason is updated
+$result = $standby2->safe_psql('postgres',
+	"SELECT slotsync_skip_reason FROM pg_replication_slots WHERE slot_name = 'lsub2_slot'"
+);
+is($result, 'wal_not_flushed', "check slot sync skip reason");
+
+# Terminate the replication connection, enabling physical replication to resume
+$repl->quit;
+
+# Confirm from the log that the slot is sync-ready now.
+$standby2->wait_for_log(
+    qr/newly created replication slot \"lsub2_slot\" is sync-ready now/,
+    $log_offset);
+
+$h->quit;
+
 done_testing();
-- 
2.51.1.windows.1

