mirror of
https://github.com/postgres/postgres.git
synced 2025-09-02 04:21:28 +03:00
Fix race conditions in replication slot operations
It is relatively easy to get a replication slot to look as still active while one process is in the process of getting rid of it; when some other process tries to "acquire" the slot, it would fail with an error message of "replication slot XYZ is active for PID N". The error message in itself is fine, except that when the intention is to drop the slot, it is unhelpful: the useful behavior would be to wait until the slot is no longer acquired, so that the drop can proceed. To implement this, we use a condition variable so that slot acquisition can be told to wait on that condition variable if the slot is already acquired, and we make any change in active_pid broadcast a signal on the condition variable. Thus, as soon as the slot is released, the drop will proceed properly. Reported by: Tom Lane Discussion: https://postgr.es/m/11904.1499039688@sss.pgh.pa.us Authors: Petr Jelínek, Álvaro Herrera
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include "fmgr.h"
|
||||
#include "access/xlog.h"
|
||||
#include "access/xlogreader.h"
|
||||
#include "storage/condition_variable.h"
|
||||
#include "storage/lwlock.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/spin.h"
|
||||
@@ -19,7 +20,7 @@
|
||||
/*
|
||||
* Behaviour of replication slots, upon release or crash.
|
||||
*
|
||||
* Slots marked as PERSISTENT are crashsafe and will not be dropped when
|
||||
* Slots marked as PERSISTENT are crash-safe and will not be dropped when
|
||||
* released. Slots marked as EPHEMERAL will be dropped when released or after
|
||||
* restarts.
|
||||
*
|
||||
@@ -117,6 +118,9 @@ typedef struct ReplicationSlot
|
||||
/* is somebody performing io on this slot? */
|
||||
LWLock io_in_progress_lock;
|
||||
|
||||
/* Condition variable signalled when active_pid changes */
|
||||
ConditionVariable active_cv;
|
||||
|
||||
/* all the remaining data is only used for logical slots */
|
||||
|
||||
/*
|
||||
@@ -162,9 +166,9 @@ extern void ReplicationSlotsShmemInit(void);
|
||||
extern void ReplicationSlotCreate(const char *name, bool db_specific,
|
||||
ReplicationSlotPersistency p);
|
||||
extern void ReplicationSlotPersist(void);
|
||||
extern void ReplicationSlotDrop(const char *name);
|
||||
extern void ReplicationSlotDrop(const char *name, bool nowait);
|
||||
|
||||
extern void ReplicationSlotAcquire(const char *name);
|
||||
extern void ReplicationSlotAcquire(const char *name, bool nowait);
|
||||
extern void ReplicationSlotRelease(void);
|
||||
extern void ReplicationSlotCleanup(void);
|
||||
extern void ReplicationSlotSave(void);
|
||||
|
Reference in New Issue
Block a user