public inbox for [email protected]
help / color / mirror / Atom feedFrom: Hayato Kuroda (Fujitsu) <[email protected]>
To: 'Michael Paquier' <[email protected]>
Cc: 'Paul A Jungwirth' <[email protected]>
Cc: Mutaamba Maasha <[email protected]>
Cc: Amit Kapila <[email protected]>
Cc: David G. Johnston <[email protected]>
Cc: Zhijie Hou (Fujitsu) <[email protected]>
Cc: Tom Lane <[email protected]>
Cc: Bertrand Drouvot <[email protected]>
Cc: [email protected] <[email protected]>
Subject: RE: ReplicationSlotRelease() crashes when the instance is in the single user mode
Date: Tue, 19 Aug 2025 12:52:24 +0000
Message-ID: <OSCPR01MB14966F06D84A7A9C26570A519F530A@OSCPR01MB14966.jpnprd01.prod.outlook.com> (raw)
In-Reply-To: <[email protected]>
References: <OSCPR01MB14966FCE16ECCF29AE0502AF2F5C42@OSCPR01MB14966.jpnprd01.prod.outlook.com>
<OSCPR01MB149660520A0E53CC53E8B66F1F5C42@OSCPR01MB14966.jpnprd01.prod.outlook.com>
<CAA4eK1LK5nZUWwNY31X6BUXdQwwzpKGKxnw+zFf-cWKm3nuCEg@mail.gmail.com>
<OSCPR01MB149669CFD736D48C4450337DDF5CD2@OSCPR01MB14966.jpnprd01.prod.outlook.com>
<CAA4eK1L8_QrYavkCy9b0Rrz8gqZRQE8kEmv3g7Tz6tsN8YuvhA@mail.gmail.com>
<OSCPR01MB149660CD4D6648CFE7FE68D34F5CC2@OSCPR01MB14966.jpnprd01.prod.outlook.com>
<CA+renyWi+bbD8M8CDAaOMGbUrXptKLCK8zQWEhXy00PJuJqNuQ@mail.gmail.com>
<OSCPR01MB14966B39B3ED21229EAEFA10FF531A@OSCPR01MB14966.jpnprd01.prod.outlook.com>
<[email protected]>
<OSCPR01MB14966D87D8EB0D9CD32C6A43DF530A@OSCPR01MB14966.jpnprd01.prod.outlook.com>
<[email protected]>
Dear Michael,
> You could also validate that using the CI, assuming that you have a
> cloned repo on github with the CI enabled. See src/tools/ci/README.
> I use that a lot with local branches for pre-commit validations where
> things could break across the board.
I have run the tests on my CI and found that windows cannot accept the test.
Per attached output, starting the postgres with the single-user mode was failed
because the user had admin permissions [1]. However, pg_ctl start command could be
done by the same user.
I'm not familiar with Windows, but according to your blogpost [2], Windows seems
to allows running some server command by generating the restricted context for
running postgres commands. In case of single-user mode, however, we directly run
the given command with the current user. So, there is a possibility that only
instance can boot only by pg_ctl.
Based on that, I want to skip the test on windows platform rather than modifying
the ci environment.
IIUC, other tests which uses --single cannot work on windows as well.
> Hmm. src/test/modules/test_misc/ makes more sense to me here. (No
> need to send an updated patch just for that.)
I did not notice the directory and looked nice. Updated.
[1]:
```
# Running: postgres --single -F -c exit_on_error=true -D C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata postgres
Execution of PostgreSQL by a user with administrative permissions is not
permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromises. See the documentation for
more information on how to properly start the server.
```
[2]: https://paquier.xyz/postgresql-2/postgres-utilities-restricted-token/
Best regards,
Hayato Kuroda
FUJITSU LIMITED
# Checking port 16164
# Found port 16164
Name: node
Data directory: C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata
Backup directory: C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/backup
Archive directory: C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/archives
Connection string: port=16164 host=C:/Windows/TEMP/HeMvBnwWt9
Log file: C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\log/049_slots_in_single_user_mode_node.log
[10:27:12.345](0.217s) # initializing database system by copying initdb template
# Running: robocopy /E /NJS /NJH /NFL /NDL /NP C:/cirrus/build/tmp_install/initdb-template C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata
# Running: C:\cirrus\build\src/test\regress\pg_regress.exe --config-auth C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata
### Starting node "node"
# Running: pg_ctl --wait --pgdata C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata --log C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\log/049_slots_in_single_user_mode_node.log --options --cluster-name=node start
waiting for server to start.... done
server started
# Postmaster PID for node "node" is 2660
### Stopping node "node" using mode fast
# Running: pg_ctl --pgdata C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata --mode fast stop
waiting for server to shut down.... done
server stopped
# No postmaster PID for node "node"
# Running: postgres --single -F -c exit_on_error=true -D C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata postgres
Execution of PostgreSQL by a user with administrative permissions is not
permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromises. See the documentation for
more information on how to properly start the server.
[10:27:18.865](6.520s) ok 1 - replication slot cannot be created in single-user mode
# Running: postgres --single -F -c exit_on_error=true -D C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata postgres
Execution of PostgreSQL by a user with administrative permissions is not
permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromises. See the documentation for
more information on how to properly start the server.
[10:27:18.927](0.062s) ok 2 - logical decoding cannot be done in single-user mode
# Running: postgres --single -F -c exit_on_error=true -D C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata postgres
Execution of PostgreSQL by a user with administrative permissions is not
permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromises. See the documentation for
more information on how to properly start the server.
[10:27:19.114](0.187s) ok 3 - replication slot cannot be advanced in single-user mode
# Running: postgres --single -F -c exit_on_error=true -D C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata postgres
Execution of PostgreSQL by a user with administrative permissions is not
permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromises. See the documentation for
more information on how to properly start the server.
[10:27:19.285](0.171s) ok 4 - replication slot cannot be copied in single-user mode
# Running: postgres --single -F -c exit_on_error=true -D C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata postgres
Execution of PostgreSQL by a user with administrative permissions is not
permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromises. See the documentation for
more information on how to properly start the server.
[10:27:19.413](0.128s) not ok 5 - replication slot can be dropped in single-user mode
[10:27:19.413](0.000s) # Failed test 'replication slot can be dropped in single-user mode'
# at C:/cirrus/src/test/recovery/t/049_slots_in_single_user_mode.pl line 35.
[10:27:19.414](0.000s) 1..5
[10:27:19.429](0.016s) # Looks like you failed 1 test of 5.
Attachments:
[text/plain] regress_log_049_slots_in_single_user_mode.txt (4.7K, ../OSCPR01MB14966F06D84A7A9C26570A519F530A@OSCPR01MB14966.jpnprd01.prod.outlook.com/2-regress_log_049_slots_in_single_user_mode.txt)
download | inline:
# Checking port 16164
# Found port 16164
Name: node
Data directory: C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata
Backup directory: C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/backup
Archive directory: C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/archives
Connection string: port=16164 host=C:/Windows/TEMP/HeMvBnwWt9
Log file: C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\log/049_slots_in_single_user_mode_node.log
[10:27:12.345](0.217s) # initializing database system by copying initdb template
# Running: robocopy /E /NJS /NJH /NFL /NDL /NP C:/cirrus/build/tmp_install/initdb-template C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata
# Running: C:\cirrus\build\src/test\regress\pg_regress.exe --config-auth C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata
### Starting node "node"
# Running: pg_ctl --wait --pgdata C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata --log C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\log/049_slots_in_single_user_mode_node.log --options --cluster-name=node start
waiting for server to start.... done
server started
# Postmaster PID for node "node" is 2660
### Stopping node "node" using mode fast
# Running: pg_ctl --pgdata C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata --mode fast stop
waiting for server to shut down.... done
server stopped
# No postmaster PID for node "node"
# Running: postgres --single -F -c exit_on_error=true -D C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata postgres
Execution of PostgreSQL by a user with administrative permissions is not
permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromises. See the documentation for
more information on how to properly start the server.
[10:27:18.865](6.520s) ok 1 - replication slot cannot be created in single-user mode
# Running: postgres --single -F -c exit_on_error=true -D C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata postgres
Execution of PostgreSQL by a user with administrative permissions is not
permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromises. See the documentation for
more information on how to properly start the server.
[10:27:18.927](0.062s) ok 2 - logical decoding cannot be done in single-user mode
# Running: postgres --single -F -c exit_on_error=true -D C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata postgres
Execution of PostgreSQL by a user with administrative permissions is not
permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromises. See the documentation for
more information on how to properly start the server.
[10:27:19.114](0.187s) ok 3 - replication slot cannot be advanced in single-user mode
# Running: postgres --single -F -c exit_on_error=true -D C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata postgres
Execution of PostgreSQL by a user with administrative permissions is not
permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromises. See the documentation for
more information on how to properly start the server.
[10:27:19.285](0.171s) ok 4 - replication slot cannot be copied in single-user mode
# Running: postgres --single -F -c exit_on_error=true -D C:\cirrus\build/testrun/recovery/049_slots_in_single_user_mode\data/t_049_slots_in_single_user_mode_node_data/pgdata postgres
Execution of PostgreSQL by a user with administrative permissions is not
permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromises. See the documentation for
more information on how to properly start the server.
[10:27:19.413](0.128s) not ok 5 - replication slot can be dropped in single-user mode
[10:27:19.413](0.000s) # Failed test 'replication slot can be dropped in single-user mode'
# at C:/cirrus/src/test/recovery/t/049_slots_in_single_user_mode.pl line 35.
[10:27:19.414](0.000s) 1..5
[10:27:19.429](0.016s) # Looks like you failed 1 test of 5.
[application/octet-stream] v7-0001-Set-ReplicationSlot-active_pid-even-in-single-use.patch (4.1K, ../OSCPR01MB14966F06D84A7A9C26570A519F530A@OSCPR01MB14966.jpnprd01.prod.outlook.com/3-v7-0001-Set-ReplicationSlot-active_pid-even-in-single-use.patch)
download | inline diff:
From d30416a303cf78639f71a3d192aa14116da28d4e Mon Sep 17 00:00:00 2001
From: Hayato Kuroda <[email protected]>
Date: Mon, 18 Aug 2025 11:47:43 +0900
Subject: [PATCH v7 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/modules/test_misc/meson.build | 1 +
.../t/008_slots_in_single_user_mode.pl | 73 +++++++++++++++++++
src/test/recovery/meson.build | 2 +-
4 files changed, 76 insertions(+), 2 deletions(-)
create mode 100644 src/test/modules/test_misc/t/008_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/modules/test_misc/meson.build b/src/test/modules/test_misc/meson.build
index 9c50de7efb0..08357d2f2e8 100644
--- a/src/test/modules/test_misc/meson.build
+++ b/src/test/modules/test_misc/meson.build
@@ -16,6 +16,7 @@ tests += {
't/005_timeouts.pl',
't/006_signal_autovacuum.pl',
't/007_catcache_inval.pl',
+ 't/008_slots_in_single_user_mode.pl',
],
},
}
diff --git a/src/test/modules/test_misc/t/008_slots_in_single_user_mode.pl b/src/test/modules/test_misc/t/008_slots_in_single_user_mode.pl
new file mode 100644
index 00000000000..4d15efd71ae
--- /dev/null
+++ b/src/test/modules/test_misc/t/008_slots_in_single_user_mode.pl
@@ -0,0 +1,73 @@
+use strict;
+use warnings;
+use PostgreSQL::Test::Cluster;
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+# Tests the slot manipulation in the single-user mode
+
+# Skip the whole thing on the windows platform
+if ($windows_os)
+{
+ plan skip_all => 'this test is not supported by this platform';
+}
+
+# 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();
diff --git a/src/test/recovery/meson.build b/src/test/recovery/meson.build
index 52993c32dbb..0b79896b61c 100644
--- a/src/test/recovery/meson.build
+++ b/src/test/recovery/meson.build
@@ -56,7 +56,7 @@ 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',
],
},
}
--
2.47.1
[application/octet-stream] v7-0002-Prohibit-slot-manipulation-while-in-single-user-m.patch (8.4K, ../OSCPR01MB14966F06D84A7A9C26570A519F530A@OSCPR01MB14966.jpnprd01.prod.outlook.com/4-v7-0002-Prohibit-slot-manipulation-while-in-single-user-m.patch)
download | inline diff:
From 2631ba04a8030fd7878765328b2aec32b81cdde6 Mon Sep 17 00:00:00 2001
From: Hayato Kuroda <[email protected]>
Date: Wed, 19 Feb 2025 11:37:26 +0900
Subject: [PATCH v7 2/2] Prohibit slot manipulation while in single-user mode
Replication-related commands are rarely used in single-user mode and have been
broken for years. This commit prohibits calling slot manipulation SQL functions
to avoid additional risk of failures. One exception is pg_drop_replication_slot.
It is still allowed because users may want to clean up their mistakes in the mode.
---
doc/src/sgml/func/func-admin.sgml | 5 ++
.../replication/logical/logicalfuncs.c | 3 ++
src/backend/replication/slot.c | 12 +++++
src/backend/replication/slotfuncs.c | 14 ++++++
src/backend/utils/adt/pg_upgrade_support.c | 3 ++
src/include/replication/slot.h | 1 +
.../t/008_slots_in_single_user_mode.pl | 48 ++++++++++++++-----
7 files changed, 75 insertions(+), 11 deletions(-)
diff --git a/doc/src/sgml/func/func-admin.sgml b/doc/src/sgml/func/func-admin.sgml
index 446fdfe56f4..cfa09e4b987 100644
--- a/doc/src/sgml/func/func-admin.sgml
+++ b/doc/src/sgml/func/func-admin.sgml
@@ -1012,6 +1012,11 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
are also relevant for replication.
</para>
+ <para>
+ Note that slot manipulation functions except <function>pg_drop_replication_slot</function>
+ cannot be used in single-user mode.
+ </para>
+
<table id="functions-replication-table">
<title>Replication Management Functions</title>
<tgroup cols="1">
diff --git a/src/backend/replication/logical/logicalfuncs.c b/src/backend/replication/logical/logicalfuncs.c
index ca53caac2f2..30877fdc3ab 100644
--- a/src/backend/replication/logical/logicalfuncs.c
+++ b/src/backend/replication/logical/logicalfuncs.c
@@ -113,6 +113,9 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin
List *options = NIL;
DecodingOutputState *p;
+ /* Slot manipulation is not allowed in single-user mode */
+ CheckSlotIsInSingleUserMode();
+
CheckSlotPermissions();
CheckLogicalDecodingRequirements();
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index fd0fdb96d42..4ca1227cc94 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -1529,6 +1529,18 @@ CheckSlotPermissions(void)
"REPLICATION")));
}
+/*
+ * Check whether the instance is in single-user mode.
+ */
+void
+CheckSlotIsInSingleUserMode(void)
+{
+ if (!IsUnderPostmaster)
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("replication slots cannot be used in single-user mode")));
+}
+
/*
* Reserve WAL for the currently active slot.
*
diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c
index 69f4c6157c5..90fe63283a1 100644
--- a/src/backend/replication/slotfuncs.c
+++ b/src/backend/replication/slotfuncs.c
@@ -17,6 +17,7 @@
#include "access/xlogrecovery.h"
#include "access/xlogutils.h"
#include "funcapi.h"
+#include "miscadmin.h"
#include "replication/logical.h"
#include "replication/slot.h"
#include "replication/slotsync.h"
@@ -76,6 +77,9 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
+ /* Slot manipulation is not allowed in single-user mode */
+ CheckSlotIsInSingleUserMode();
+
CheckSlotPermissions();
CheckSlotRequirements();
@@ -182,6 +186,9 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS)
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
+ /* Slot manipulation is not allowed in single-user mode */
+ CheckSlotIsInSingleUserMode();
+
CheckSlotPermissions();
CheckLogicalDecodingRequirements();
@@ -521,6 +528,9 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
Assert(!MyReplicationSlot);
+ /* Slot manipulation is not allowed in single-user mode */
+ CheckSlotIsInSingleUserMode();
+
CheckSlotPermissions();
if (XLogRecPtrIsInvalid(moveto))
@@ -618,9 +628,13 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
TupleDesc tupdesc;
HeapTuple tuple;
+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
+ /* Slot manipulation is not allowed in single-user mode */
+ CheckSlotIsInSingleUserMode();
+
CheckSlotPermissions();
if (logical_slot)
diff --git a/src/backend/utils/adt/pg_upgrade_support.c b/src/backend/utils/adt/pg_upgrade_support.c
index a4f8b4faa90..337f705b34b 100644
--- a/src/backend/utils/adt/pg_upgrade_support.c
+++ b/src/backend/utils/adt/pg_upgrade_support.c
@@ -296,6 +296,9 @@ binary_upgrade_logical_slot_has_caught_up(PG_FUNCTION_ARGS)
*/
Assert(has_rolreplication(GetUserId()));
+ /* Slot manipulation is not allowed in single-user mode */
+ CheckSlotIsInSingleUserMode();
+
slot_name = PG_GETARG_NAME(0);
/* Acquire the given slot */
diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h
index e8fc342d1a9..b4d89760f96 100644
--- a/src/include/replication/slot.h
+++ b/src/include/replication/slot.h
@@ -342,6 +342,7 @@ extern void CheckPointReplicationSlots(bool is_shutdown);
extern void CheckSlotRequirements(void);
extern void CheckSlotPermissions(void);
+extern void CheckSlotIsInSingleUserMode(void);
extern ReplicationSlotInvalidationCause
GetSlotInvalidationCause(const char *cause_name);
extern const char *GetSlotInvalidationCauseName(ReplicationSlotInvalidationCause cause);
diff --git a/src/test/modules/test_misc/t/008_slots_in_single_user_mode.pl b/src/test/modules/test_misc/t/008_slots_in_single_user_mode.pl
index 4d15efd71ae..b3d9fe2fc33 100644
--- a/src/test/modules/test_misc/t/008_slots_in_single_user_mode.pl
+++ b/src/test/modules/test_misc/t/008_slots_in_single_user_mode.pl
@@ -27,9 +27,31 @@ sub run_test_in_single_user_mode
],
\$commands);
+ return $result;
+}
+
+# Wrapper function for run_test_in_single_user_mode. This would be used when
+# the input command succeeds.
+sub run_test_in_single_user_mode_success
+{
+ my ($node, $commands, $testname) = @_;
+
+ my $result = run_test_in_single_user_mode($node, $commands, $testname);
+
ok($result, $testname);
}
+# Wrapper function for run_test_in_single_user_mode. This would be used when
+# the input command fails.
+sub run_test_in_single_user_mode_fail
+{
+ my ($node, $commands, $testname) = @_;
+
+ my $result = run_test_in_single_user_mode($node, $commands, $testname);
+
+ ok(!$result, $testname);
+}
+
my $slotname = 'test_slot';
# Initialize a node
@@ -38,34 +60,38 @@ $node->init(allows_streaming => "logical");
$node->start;
# Define initial table
-$node->safe_psql('postgres', "CREATE TABLE foo (id int)");
+$node->safe_psql(
+ 'postgres', qq(
+CREATE TABLE foo (id int);
+SELECT pg_create_logical_replication_slot('$slotname', 'test_decoding');
+));
# Stop the node to run and test in single-user mode
$node->stop;
-run_test_in_single_user_mode(
+run_test_in_single_user_mode_fail(
$node,
- "SELECT pg_create_logical_replication_slot('$slotname', 'test_decoding')",
- "replication slot can be created in single-user mode");
+ "SELECT pg_create_logical_replication_slot('another_slot', 'test_decoding')",
+ "replication slot cannot be created in single-user mode");
-run_test_in_single_user_mode(
+run_test_in_single_user_mode_fail(
$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");
+ "logical decoding cannot be done in single-user mode");
-run_test_in_single_user_mode(
+run_test_in_single_user_mode_fail(
$node,
"SELECT pg_replication_slot_advance('$slotname', pg_current_wal_lsn())",
- "replication slot can be advanced in single-user mode");
+ "replication slot cannot be advanced in single-user mode");
-run_test_in_single_user_mode(
+run_test_in_single_user_mode_fail(
$node,
"SELECT pg_copy_logical_replication_slot('$slotname', 'dest_slot')",
- "replication slot can be copied in single-user mode");
+ "replication slot cannot be copied in single-user mode");
-run_test_in_single_user_mode(
+run_test_in_single_user_mode_success(
$node,
"SELECT pg_drop_replication_slot('$slotname')",
"replication slot can be dropped in single-user mode");
--
2.47.1
view thread (31+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
Subject: RE: ReplicationSlotRelease() crashes when the instance is in the single user mode
In-Reply-To: <OSCPR01MB14966F06D84A7A9C26570A519F530A@OSCPR01MB14966.jpnprd01.prod.outlook.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox