Skip to content

Commit 7cec139

Browse files
author
Commitfest Bot
committed
[CF 5626] v4 - ReplicationSlotRelease() crashes when the instance is in the single user mode
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/5626 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/OSCPR01MB149669CFD736D48C4450337DDF5CD2@OSCPR01MB14966.jpnprd01.prod.outlook.com Author(s): Hayato Kuroda
2 parents f132815 + d815528 commit 7cec139

File tree

4 files changed

+27
-0
lines changed

4 files changed

+27
-0
lines changed

src/backend/replication/logical/logicalfuncs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin
113113
List *options = NIL;
114114
DecodingOutputState *p;
115115

116+
CheckSlotIsInSingleUserMode();
117+
116118
CheckSlotPermissions();
117119

118120
CheckLogicalDecodingRequirements();

src/backend/replication/slot.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,18 @@ CheckSlotPermissions(void)
14421442
"REPLICATION")));
14431443
}
14441444

1445+
/*
1446+
* Check whether the instance is in single-user mode.
1447+
*/
1448+
void
1449+
CheckSlotIsInSingleUserMode(void)
1450+
{
1451+
if (!IsUnderPostmaster)
1452+
ereport(ERROR,
1453+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1454+
errmsg("replication slots cannot be used in single-user mode")));
1455+
}
1456+
14451457
/*
14461458
* Reserve WAL for the currently active slot.
14471459
*

src/backend/replication/slotfuncs.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "access/xlogrecovery.h"
1818
#include "access/xlogutils.h"
1919
#include "funcapi.h"
20+
#include "miscadmin.h"
2021
#include "replication/logical.h"
2122
#include "replication/slot.h"
2223
#include "replication/slotsync.h"
@@ -76,6 +77,8 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS)
7677
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
7778
elog(ERROR, "return type must be a row type");
7879

80+
CheckSlotIsInSingleUserMode();
81+
7982
CheckSlotPermissions();
8083

8184
CheckSlotRequirements();
@@ -182,6 +185,8 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS)
182185
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
183186
elog(ERROR, "return type must be a row type");
184187

188+
CheckSlotIsInSingleUserMode();
189+
185190
CheckSlotPermissions();
186191

187192
CheckLogicalDecodingRequirements();
@@ -521,6 +526,8 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
521526

522527
Assert(!MyReplicationSlot);
523528

529+
CheckSlotIsInSingleUserMode();
530+
524531
CheckSlotPermissions();
525532

526533
if (XLogRecPtrIsInvalid(moveto))
@@ -618,9 +625,12 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
618625
TupleDesc tupdesc;
619626
HeapTuple tuple;
620627

628+
621629
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
622630
elog(ERROR, "return type must be a row type");
623631

632+
CheckSlotIsInSingleUserMode();
633+
624634
CheckSlotPermissions();
625635

626636
if (logical_slot)
@@ -898,6 +908,8 @@ pg_sync_replication_slots(PG_FUNCTION_ARGS)
898908
char *err;
899909
StringInfoData app_name;
900910

911+
CheckSlotIsInSingleUserMode();
912+
901913
CheckSlotPermissions();
902914

903915
if (!RecoveryInProgress())

src/include/replication/slot.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ extern void CheckPointReplicationSlots(bool is_shutdown);
306306

307307
extern void CheckSlotRequirements(void);
308308
extern void CheckSlotPermissions(void);
309+
extern void CheckSlotIsInSingleUserMode(void);
309310
extern ReplicationSlotInvalidationCause
310311
GetSlotInvalidationCause(const char *cause_name);
311312
extern const char *GetSlotInvalidationCauseName(ReplicationSlotInvalidationCause cause);

0 commit comments

Comments
 (0)