From e7d7de8fc99258ea826fc6269497313fefb417c1 Mon Sep 17 00:00:00 2001 From: Hayato Kuroda Date: Mon, 18 Aug 2025 11:47:43 +0900 Subject: [PATCH v6 1/2] Set ReplicationSlot::active_pid even in single-user mode Slot manipulation functions except drop could be failed in single-user mode, because active_pid was not set. Actually the attribute is no-op in the mode but fix the inconsisntency anyway. --- src/backend/replication/slot.c | 2 +- src/test/recovery/meson.build | 3 +- .../t/049_slots_in_single_user_mode.pl | 67 +++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 src/test/recovery/t/049_slots_in_single_user_mode.pl diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index 8605776ad86..fd0fdb96d42 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -653,7 +653,7 @@ retry: } else { - active_pid = MyProcPid; + s->active_pid = active_pid = MyProcPid; ReplicationSlotSetInactiveSince(s, 0, true); } LWLockRelease(ReplicationSlotControlLock); diff --git a/src/test/recovery/meson.build b/src/test/recovery/meson.build index 52993c32dbb..7b1fe30f112 100644 --- a/src/test/recovery/meson.build +++ b/src/test/recovery/meson.build @@ -56,7 +56,8 @@ tests += { 't/045_archive_restartpoint.pl', 't/046_checkpoint_logical_slot.pl', 't/047_checkpoint_physical_slot.pl', - 't/048_vacuum_horizon_floor.pl' + 't/048_vacuum_horizon_floor.pl', + 't/049_slots_in_single_user_mode.pl', ], }, } diff --git a/src/test/recovery/t/049_slots_in_single_user_mode.pl b/src/test/recovery/t/049_slots_in_single_user_mode.pl new file mode 100644 index 00000000000..de32160be07 --- /dev/null +++ b/src/test/recovery/t/049_slots_in_single_user_mode.pl @@ -0,0 +1,67 @@ +use strict; +use warnings; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +# Tests the slot manipulation in the single-user mode + +# Run passed commands in single-user mode. The return value from the command is +# passed through. +sub run_test_in_single_user_mode +{ + my ($node, $commands, $testname) = @_; + + my $result = run_log( + [ + 'postgres', '--single', '-F', + '-c' => 'exit_on_error=true', + '-D' => $node->data_dir, + 'postgres' + ], + \$commands); + + ok($result, $testname); +} + +my $slotname = 'test_slot'; + +# Initialize a node +my $node = PostgreSQL::Test::Cluster->new('node'); +$node->init(allows_streaming => "logical"); +$node->start; + +# Define initial table +$node->safe_psql('postgres', "CREATE TABLE foo (id int)"); + +# Stop the node to run and test in single-user mode +$node->stop; + +run_test_in_single_user_mode( + $node, + "SELECT pg_create_logical_replication_slot('$slotname', 'test_decoding')", + "replication slot can be created in single-user mode"); + +run_test_in_single_user_mode( + $node, qq( +INSERT INTO foo VALUES (1); +SELECT count(1) FROM pg_logical_slot_get_changes('$slotname', NULL, NULL); +), + "logical decoding be done in single-user mode"); + +run_test_in_single_user_mode( + $node, + "SELECT pg_replication_slot_advance('$slotname', pg_current_wal_lsn())", + "replication slot can be advanced in single-user mode"); + +run_test_in_single_user_mode( + $node, + "SELECT pg_copy_logical_replication_slot('$slotname', 'dest_slot')", + "replication slot can be copied in single-user mode"); + +run_test_in_single_user_mode( + $node, + "SELECT pg_drop_replication_slot('$slotname')", + "replication slot can be dropped in single-user mode"); + +done_testing(); -- 2.47.1