##################################################
# Test that the synchronized slot will be dropped if the corresponding remote
# slot on the primary server has been dropped.
-#
-# Note: Both slots need to be dropped for the next test to work
##################################################
$primary->psql('postgres', "SELECT pg_drop_replication_slot('lsub2_slot');");
-$primary->psql('postgres', "SELECT pg_drop_replication_slot('lsub1_slot');");
$standby1->safe_psql('postgres', "SELECT pg_sync_replication_slots();");
is( $standby1->safe_psql(
'postgres',
- q{SELECT count(*) = 0 FROM pg_replication_slots WHERE slot_name IN ('lsub1_slot', 'lsub2_slot');}
+ q{SELECT count(*) = 0 FROM pg_replication_slots WHERE slot_name = 'lsub2_slot';}
),
"t",
'synchronized slot has been dropped');
-##################################################
-# Verify that slotsync skip statistics are correctly updated when the
-# slotsync operation is skipped.
-##################################################
-
-# Create a logical replication slot and create some DDL on the primary so
-# that the slot lags behind the standby.
-$primary->safe_psql(
- 'postgres', qq(
- SELECT pg_create_logical_replication_slot('lsub1_slot', 'pgoutput', false, false, true);
- CREATE TABLE wal_push(a int);
-));
-$primary->wait_for_replay_catchup($standby1);
-
-my $log_offset = -s $standby1->logfile;
-
-# Enable slot sync worker.
-$standby1->append_conf('postgresql.conf', qq(sync_replication_slots = on));
-$standby1->reload;
-
-# Confirm that the slot sync worker is able to start.
-$standby1->wait_for_log(qr/slot sync worker started/, $log_offset);
-
-# Confirm that the slot sync is skipped due to the remote slot lagging behind
-$standby1->wait_for_log(
- qr/could not synchronize replication slot \"lsub1_slot\"/, $log_offset);
-
-# Confirm that the slotsync skip statistics is updated
-$result = $standby1->safe_psql('postgres',
- "SELECT slotsync_skip_count > 0 FROM pg_stat_replication_slots WHERE slot_name = 'lsub1_slot'"
-);
-is($result, 't', "check slot sync skip count increments");
-
-# Clean the table
-$primary->safe_psql(
- 'postgres', qq(
- DROP TABLE wal_push;
-));
-$primary->wait_for_replay_catchup($standby1);
-
-# Re-create the logical replication slot and sync it to standby for further tests
-$primary->safe_psql(
- 'postgres', qq(
- SELECT pg_drop_replication_slot('lsub1_slot');
- SELECT pg_create_logical_replication_slot('lsub1_slot', 'pgoutput', false, false, true);
-));
-$standby1->wait_for_log(
- qr/newly created replication slot \"lsub1_slot\" is sync-ready now/,
- $log_offset);
-
-$standby1->append_conf('postgresql.conf', qq(sync_replication_slots = off));
-$standby1->reload;
-
##################################################
# Test that if the synchronized slot is invalidated while the remote slot is
# still valid, the slot will be dropped and re-created on the standby by
# the failover slots.
$primary->wait_for_replay_catchup($standby1);
-$log_offset = -s $standby1->logfile;
+my $log_offset = -s $standby1->logfile;
# Synchronize the primary server slots to the standby.
$standby1->safe_psql('postgres', "SELECT pg_sync_replication_slots();");
is($result, '1', "data can be consumed using snap_test_slot");
+##################################################
+# Remove any unnecessary replication slots and clear pending transactions on the
+# primary server to ensure a clean environment.
+##################################################
+
+$primary->psql(
+ 'postgres', qq(
+ SELECT pg_drop_replication_slot('sb1_slot');
+ SELECT pg_drop_replication_slot('lsub1_slot');
+ SELECT pg_drop_replication_slot('snap_test_slot');
+));
+
+$subscriber2->safe_psql('postgres', 'DROP SUBSCRIPTION regress_mysub2;');
+
+# Verify that all slots have been removed except the one necessary for standby2,
+# which is needed for further testing.
+is( $primary->safe_psql(
+ 'postgres',
+ q{SELECT count(*) = 0 FROM pg_replication_slots WHERE slot_name != 'sb2_slot';}
+ ),
+ "t",
+ 'all replication slots have been dropped except the physical slot used by standby2'
+);
+
+# Commit the pending prepared transaction
+$primary->safe_psql('postgres', "COMMIT PREPARED 'test_twophase_slotsync';");
+$primary->wait_for_replay_catchup($standby2);
+
+##################################################
+# Verify that slotsync skip statistics are correctly updated when the
+# slotsync operation is skipped.
+##################################################
+
+# Create a logical replication slot and create some DDL on the primary so
+# that the slot lags behind the standby.
+$primary->safe_psql(
+ 'postgres', qq(
+ SELECT pg_create_logical_replication_slot('lsub1_slot', 'pgoutput', false, false, true);
+ CREATE TABLE wal_push(a int);
+));
+$primary->wait_for_replay_catchup($standby2);
+
+$log_offset = -s $standby2->logfile;
+
+# Enable slot sync worker
+$standby2->append_conf(
+ 'postgresql.conf', qq(
+hot_standby_feedback = on
+primary_conninfo = '$connstr_1 dbname=postgres'
+log_min_messages = 'debug2'
+sync_replication_slots = on
+));
+
+$standby2->reload;
+
+# Confirm that the slot sync worker is able to start.
+$standby2->wait_for_log(qr/slot sync worker started/, $log_offset);
+
+# Confirm that the slot sync is skipped due to the remote slot lagging behind
+$standby2->wait_for_log(
+ qr/could not synchronize replication slot \"lsub1_slot\"/, $log_offset);
+
+# Confirm that the slotsync skip statistics is updated
+$result = $standby2->safe_psql('postgres',
+ "SELECT slotsync_skip_count > 0 FROM pg_stat_replication_slots WHERE slot_name = 'lsub1_slot'"
+);
+is($result, 't', "check slot sync skip count increments");
+
done_testing();