Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3c5f9f1

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 1e5ef3a commit 3c5f9f1

File tree

1 file changed

+17
-27
lines changed

1 file changed

+17
-27
lines changed

src/backend/replication/slot.c

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2456,18 +2456,15 @@ validate_sync_standby_slots(char *rawname, List **elemlist)
24562456
{
24572457
GUC_check_errdetail("List syntax is invalid.");
24582458
}
2459-
else if (!ReplicationSlotCtl)
2459+
else if (MyProc)
24602460
{
24612461
/*
2462-
* We cannot validate the replication slot if the replication slots'
2463-
* data has not been initialized. This is ok as we will anyway
2464-
* validate the specified slot when waiting for them to catch up. See
2465-
* StandbySlotsHaveCaughtup() for details.
2462+
* Check that each specified slot exist and is physical.
2463+
*
2464+
* Because we need an LWLock, we cannot do this on processes without a
2465+
* PGPROC, so we skip it there; but see comments in
2466+
* StandbySlotsHaveCaughtup() as to why that's not a problem.
24662467
*/
2467-
}
2468-
else
2469-
{
2470-
/* Check that the specified slots exist and are logical slots */
24712468
LWLockAcquire(ReplicationSlotControlLock, LW_SHARED);
24722469

24732470
foreach_ptr(char, name, *elemlist)
@@ -2649,18 +2646,18 @@ StandbySlotsHaveCaughtup(XLogRecPtr wait_for_lsn, int elevel)
26492646

26502647
slot = SearchNamedReplicationSlot(name, false);
26512648

2649+
/*
2650+
* If a slot name provided in synchronized_standby_slots does not
2651+
* exist, report a message and exit the loop.
2652+
*
2653+
* Though validate_sync_standby_slots (the GUC check_hook) tries to
2654+
* avoid this, it can nonetheless happen because the user can specify
2655+
* a nonexistent slot name before server startup. That function cannot
2656+
* validate such a slot during startup, as ReplicationSlotCtl is not
2657+
* initialized by then. Also, the user might have dropped one slot.
2658+
*/
26522659
if (!slot)
26532660
{
2654-
/*
2655-
* If a slot name provided in synchronized_standby_slots does not
2656-
* exist, report a message and exit the loop. A user can specify a
2657-
* slot name that does not exist just before the server startup.
2658-
* The GUC check_hook(validate_sync_standby_slots) cannot validate
2659-
* such a slot during startup as the ReplicationSlotCtl shared
2660-
* memory is not initialized at that time. It is also possible for
2661-
* a user to drop the slot in synchronized_standby_slots
2662-
* afterwards.
2663-
*/
26642661
ereport(elevel,
26652662
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
26662663
errmsg("replication slot \"%s\" specified in parameter \"%s\" does not exist",
@@ -2672,16 +2669,9 @@ StandbySlotsHaveCaughtup(XLogRecPtr wait_for_lsn, int elevel)
26722669
break;
26732670
}
26742671

2672+
/* Same as above: if a slot is not physical, exit the loop. */
26752673
if (SlotIsLogical(slot))
26762674
{
2677-
/*
2678-
* If a logical slot name is provided in
2679-
* synchronized_standby_slots, report a message and exit the loop.
2680-
* Similar to the non-existent case, a user can specify a logical
2681-
* slot name in synchronized_standby_slots before the server
2682-
* startup, or drop an existing physical slot and recreate a
2683-
* logical slot with the same name.
2684-
*/
26852675
ereport(elevel,
26862676
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
26872677
errmsg("cannot specify logical replication slot \"%s\" in parameter \"%s\"",

0 commit comments

Comments
 (0)