From dff4fa6758d4992f0e49879874c317317e122fee Mon Sep 17 00:00:00 2001 From: Hayato Kuroda Date: Wed, 19 Feb 2025 11:37:26 +0900 Subject: [PATCH v3] Prohibit slot operations while in the single user mode --- .../replication/logical/logicalfuncs.c | 9 +++++ src/backend/replication/slotfuncs.c | 33 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/backend/replication/logical/logicalfuncs.c b/src/backend/replication/logical/logicalfuncs.c index ca53caac2f..a3b52c481e 100644 --- a/src/backend/replication/logical/logicalfuncs.c +++ b/src/backend/replication/logical/logicalfuncs.c @@ -113,6 +113,15 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin List *options = NIL; DecodingOutputState *p; + if (!IsUnderPostmaster) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot use function %s in single-user mode", + confirm ? (binary ? "pg_logical_slot_get_binary_changes" : + "pg_logical_slot_get_changes") : + (binary ? "pg_logical_slot_peek_binary_changes" : + "pg_logical_slot_peek_changes")))); + CheckSlotPermissions(); CheckLogicalDecodingRequirements(); diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index f652ec8a73..d7c4d8b9af 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" @@ -73,6 +74,12 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS) HeapTuple tuple; Datum result; + if (!IsUnderPostmaster) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot use function %s in single-user mode", + "pg_create_physical_replication_slot"))); + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "return type must be a row type"); @@ -179,6 +186,12 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS) Datum values[2]; bool nulls[2]; + if (!IsUnderPostmaster) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot use function %s in single-user mode", + "pg_create_logical_replication_slot"))); + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "return type must be a row type"); @@ -515,6 +528,12 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS) Assert(!MyReplicationSlot); + if (!IsUnderPostmaster) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot use function %s in single-user mode", + "pg_replication_slot_advance"))); + CheckSlotPermissions(); if (XLogRecPtrIsInvalid(moveto)) @@ -612,6 +631,14 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot) TupleDesc tupdesc; HeapTuple tuple; + if (!IsUnderPostmaster) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot use function %s in single-user mode", + logical_slot ? + "pg_copy_logical_replication_slot" : + "pg_copy_physical_replication_slot"))); + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "return type must be a row type"); @@ -866,6 +893,12 @@ pg_sync_replication_slots(PG_FUNCTION_ARGS) char *err; StringInfoData app_name; + if (!IsUnderPostmaster) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot use function %s in single-user mode", + "pg_sync_replication_slots"))); + CheckSlotPermissions(); if (!RecoveryInProgress()) -- 2.43.5