Skip to content

Commit 9abdc18

Browse files
committed
Fix synchronized_standby_slots GUC check hook
The validate_sync_standby_slots subroutine requires an LWLock, so it cannot run in processes without PGPROC; skip it there to avoid a crash. This replaces the current test for ReplicationSlotCtl being not null, which appears to be a solution for the same problem but less general. I also rewrote a related comment that mentioned ReplicationSlotCtl in StandbySlotsHaveCaughtup. This code came in with commit bf279dd; backpatch to 17. Reported-by: Gabriele Bartolini <gabriele.bartolini@enterprisedb.com> Reviewed-by: Amit Kapila <amit.kapila16@gmail.com> Reviewed-by: Zhijie Hou <houzj.fnst@fujitsu.com> Discussion: https://postgr.es/m/202411281216.sutbxtr6idnn@alvherre.pgsql
1 parent 5ffbbcf commit 9abdc18

File tree

1 file changed

+17
-27
lines changed

1 file changed

+17
-27
lines changed

src/backend/replication/slot.c

+17-27
Original file line numberDiff line numberDiff line change
@@ -2428,18 +2428,15 @@ validate_sync_standby_slots(char *rawname, List **elemlist)
24282428
{
24292429
GUC_check_errdetail("List syntax is invalid.");
24302430
}
2431-
else if (!ReplicationSlotCtl)
2431+
else if (MyProc)
24322432
{
24332433
/*
2434-
* We cannot validate the replication slot if the replication slots'
2435-
* data has not been initialized. This is ok as we will anyway
2436-
* validate the specified slot when waiting for them to catch up. See
2437-
* StandbySlotsHaveCaughtup() for details.
2434+
* Check that each specified slot exist and is physical.
2435+
*
2436+
* Because we need an LWLock, we cannot do this on processes without a
2437+
* PGPROC, so we skip it there; but see comments in
2438+
* StandbySlotsHaveCaughtup() as to why that's not a problem.
24382439
*/
2439-
}
2440-
else
2441-
{
2442-
/* Check that the specified slots exist and are logical slots */
24432440
LWLockAcquire(ReplicationSlotControlLock, LW_SHARED);
24442441

24452442
foreach_ptr(char, name, *elemlist)
@@ -2621,18 +2618,18 @@ StandbySlotsHaveCaughtup(XLogRecPtr wait_for_lsn, int elevel)
26212618

26222619
slot = SearchNamedReplicationSlot(name, false);
26232620

2621+
/*
2622+
* If a slot name provided in synchronized_standby_slots does not
2623+
* exist, report a message and exit the loop.
2624+
*
2625+
* Though validate_sync_standby_slots (the GUC check_hook) tries to
2626+
* avoid this, it can nonetheless happen because the user can specify
2627+
* a nonexistent slot name before server startup. That function cannot
2628+
* validate such a slot during startup, as ReplicationSlotCtl is not
2629+
* initialized by then. Also, the user might have dropped one slot.
2630+
*/
26242631
if (!slot)
26252632
{
2626-
/*
2627-
* If a slot name provided in synchronized_standby_slots does not
2628-
* exist, report a message and exit the loop. A user can specify a
2629-
* slot name that does not exist just before the server startup.
2630-
* The GUC check_hook(validate_sync_standby_slots) cannot validate
2631-
* such a slot during startup as the ReplicationSlotCtl shared
2632-
* memory is not initialized at that time. It is also possible for
2633-
* a user to drop the slot in synchronized_standby_slots
2634-
* afterwards.
2635-
*/
26362633
ereport(elevel,
26372634
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
26382635
errmsg("replication slot \"%s\" specified in parameter \"%s\" does not exist",
@@ -2644,16 +2641,9 @@ StandbySlotsHaveCaughtup(XLogRecPtr wait_for_lsn, int elevel)
26442641
break;
26452642
}
26462643

2644+
/* Same as above: if a slot is not physical, exit the loop. */
26472645
if (SlotIsLogical(slot))
26482646
{
2649-
/*
2650-
* If a logical slot name is provided in
2651-
* synchronized_standby_slots, report a message and exit the loop.
2652-
* Similar to the non-existent case, a user can specify a logical
2653-
* slot name in synchronized_standby_slots before the server
2654-
* startup, or drop an existing physical slot and recreate a
2655-
* logical slot with the same name.
2656-
*/
26572647
ereport(elevel,
26582648
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
26592649
errmsg("cannot specify logical replication slot \"%s\" in parameter \"%s\"",

0 commit comments

Comments
 (0)