mirror of
https://github.com/postgres/postgres.git
synced 2025-09-03 15:22:11 +03:00
Add 'active_in' column to pg_replication_slots.
Right now it is visible whether a replication slot is active in any session, but not in which. Adding the active_in column, containing the pid of the backend having acquired the slot, makes it much easier to associate pg_replication_slots entries with the corresponding pg_stat_replication/pg_stat_activity row. This should have been done from the start, but I (Andres) dropped the ball there somehow. Author: Craig Ringer, revised by me Discussion: CAMsr+YFKgZca5_7_ouaMWxA5PneJC9LNViPzpDHusaPhU9pA7g@mail.gmail.com
This commit is contained in:
@@ -262,7 +262,7 @@ ReplicationSlotCreate(const char *name, bool db_specific,
|
||||
* be doing that. So it's safe to initialize the slot.
|
||||
*/
|
||||
Assert(!slot->in_use);
|
||||
Assert(!slot->active);
|
||||
Assert(slot->active_pid == 0);
|
||||
slot->data.persistency = persistency;
|
||||
slot->data.xmin = InvalidTransactionId;
|
||||
slot->effective_xmin = InvalidTransactionId;
|
||||
@@ -291,8 +291,8 @@ ReplicationSlotCreate(const char *name, bool db_specific,
|
||||
volatile ReplicationSlot *vslot = slot;
|
||||
|
||||
SpinLockAcquire(&slot->mutex);
|
||||
Assert(!vslot->active);
|
||||
vslot->active = true;
|
||||
Assert(vslot->active_pid == 0);
|
||||
vslot->active_pid = MyProcPid;
|
||||
SpinLockRelease(&slot->mutex);
|
||||
MyReplicationSlot = slot;
|
||||
}
|
||||
@@ -314,7 +314,7 @@ ReplicationSlotAcquire(const char *name)
|
||||
{
|
||||
ReplicationSlot *slot = NULL;
|
||||
int i;
|
||||
bool active = false;
|
||||
int active_pid = 0;
|
||||
|
||||
Assert(MyReplicationSlot == NULL);
|
||||
|
||||
@@ -331,8 +331,9 @@ ReplicationSlotAcquire(const char *name)
|
||||
volatile ReplicationSlot *vslot = s;
|
||||
|
||||
SpinLockAcquire(&s->mutex);
|
||||
active = vslot->active;
|
||||
vslot->active = true;
|
||||
active_pid = vslot->active_pid;
|
||||
if (active_pid == 0)
|
||||
vslot->active_pid = MyProcPid;
|
||||
SpinLockRelease(&s->mutex);
|
||||
slot = s;
|
||||
break;
|
||||
@@ -345,10 +346,11 @@ ReplicationSlotAcquire(const char *name)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("replication slot \"%s\" does not exist", name)));
|
||||
if (active)
|
||||
if (active_pid != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_IN_USE),
|
||||
errmsg("replication slot \"%s\" is already active", name)));
|
||||
errmsg("replication slot \"%s\" is already active for pid %d",
|
||||
name, active_pid)));
|
||||
|
||||
/* We made this slot active, so it's ours now. */
|
||||
MyReplicationSlot = slot;
|
||||
@@ -363,7 +365,7 @@ ReplicationSlotRelease(void)
|
||||
{
|
||||
ReplicationSlot *slot = MyReplicationSlot;
|
||||
|
||||
Assert(slot != NULL && slot->active);
|
||||
Assert(slot != NULL && slot->active_pid != 0);
|
||||
|
||||
if (slot->data.persistency == RS_EPHEMERAL)
|
||||
{
|
||||
@@ -380,7 +382,7 @@ ReplicationSlotRelease(void)
|
||||
volatile ReplicationSlot *vslot = slot;
|
||||
|
||||
SpinLockAcquire(&slot->mutex);
|
||||
vslot->active = false;
|
||||
vslot->active_pid = 0;
|
||||
SpinLockRelease(&slot->mutex);
|
||||
}
|
||||
|
||||
@@ -460,7 +462,7 @@ ReplicationSlotDropAcquired(void)
|
||||
bool fail_softly = slot->data.persistency == RS_EPHEMERAL;
|
||||
|
||||
SpinLockAcquire(&slot->mutex);
|
||||
vslot->active = false;
|
||||
vslot->active_pid = 0;
|
||||
SpinLockRelease(&slot->mutex);
|
||||
|
||||
ereport(fail_softly ? WARNING : ERROR,
|
||||
@@ -477,7 +479,7 @@ ReplicationSlotDropAcquired(void)
|
||||
* scanning the array.
|
||||
*/
|
||||
LWLockAcquire(ReplicationSlotControlLock, LW_EXCLUSIVE);
|
||||
slot->active = false;
|
||||
slot->active_pid = 0;
|
||||
slot->in_use = false;
|
||||
LWLockRelease(ReplicationSlotControlLock);
|
||||
|
||||
@@ -749,7 +751,7 @@ ReplicationSlotsCountDBSlots(Oid dboid, int *nslots, int *nactive)
|
||||
/* count slots with spinlock held */
|
||||
SpinLockAcquire(&s->mutex);
|
||||
(*nslots)++;
|
||||
if (s->active)
|
||||
if (s->active_pid != 0)
|
||||
(*nactive)++;
|
||||
SpinLockRelease(&s->mutex);
|
||||
}
|
||||
@@ -1227,7 +1229,7 @@ RestoreSlotFromDisk(const char *name)
|
||||
slot->candidate_restart_valid = InvalidXLogRecPtr;
|
||||
|
||||
slot->in_use = true;
|
||||
slot->active = false;
|
||||
slot->active_pid = 0;
|
||||
|
||||
restored = true;
|
||||
break;
|
||||
|
@@ -158,7 +158,7 @@ pg_drop_replication_slot(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_get_replication_slots(PG_FUNCTION_ARGS)
|
||||
{
|
||||
#define PG_GET_REPLICATION_SLOTS_COLS 8
|
||||
#define PG_GET_REPLICATION_SLOTS_COLS 9
|
||||
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
|
||||
TupleDesc tupdesc;
|
||||
Tuplestorestate *tupstore;
|
||||
@@ -206,7 +206,7 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
|
||||
TransactionId xmin;
|
||||
TransactionId catalog_xmin;
|
||||
XLogRecPtr restart_lsn;
|
||||
bool active;
|
||||
pid_t active_pid;
|
||||
Oid database;
|
||||
NameData slot_name;
|
||||
NameData plugin;
|
||||
@@ -227,7 +227,7 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
|
||||
namecpy(&slot_name, &slot->data.name);
|
||||
namecpy(&plugin, &slot->data.plugin);
|
||||
|
||||
active = slot->active;
|
||||
active_pid = slot->active_pid;
|
||||
}
|
||||
SpinLockRelease(&slot->mutex);
|
||||
|
||||
@@ -251,7 +251,12 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
|
||||
else
|
||||
values[i++] = database;
|
||||
|
||||
values[i++] = BoolGetDatum(active);
|
||||
values[i++] = BoolGetDatum(active_pid != 0);
|
||||
|
||||
if (active_pid != 0)
|
||||
values[i++] = Int32GetDatum(active_pid);
|
||||
else
|
||||
nulls[i++] = true;
|
||||
|
||||
if (xmin != InvalidTransactionId)
|
||||
values[i++] = TransactionIdGetDatum(xmin);
|
||||
|
Reference in New Issue
Block a user