fix_slot_xmin_race_condition.patch
application/octet-stream
Filename: fix_slot_xmin_race_condition.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/replication/slot.c | 7 | 1 |
| src/backend/storage/ipc/procarray.c | 2 | 9 |
| src/include/storage/procarray.h | 1 | 1 |
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 899acfd912..b781d2ea81 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -840,6 +840,9 @@ ReplicationSlotsComputeRequiredXmin(bool already_locked)
Assert(ReplicationSlotCtl != NULL);
+ if (!already_locked)
+ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
+
LWLockAcquire(ReplicationSlotControlLock, LW_SHARED);
for (i = 0; i < max_replication_slots; i++)
@@ -878,7 +881,10 @@ ReplicationSlotsComputeRequiredXmin(bool already_locked)
LWLockRelease(ReplicationSlotControlLock);
- ProcArraySetReplicationSlotXmin(agg_xmin, agg_catalog_xmin, already_locked);
+ ProcArraySetReplicationSlotXmin(agg_xmin, agg_catalog_xmin);
+
+ if (!already_locked)
+ LWLockRelease(ProcArrayLock);
}
/*
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 0176f30270..eb74c34dbc 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -3899,20 +3899,13 @@ TerminateOtherDBBackends(Oid databaseId)
* replication slots.
*/
void
-ProcArraySetReplicationSlotXmin(TransactionId xmin, TransactionId catalog_xmin,
- bool already_locked)
+ProcArraySetReplicationSlotXmin(TransactionId xmin, TransactionId catalog_xmin)
{
- Assert(!already_locked || LWLockHeldByMe(ProcArrayLock));
-
- if (!already_locked)
- LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
+ Assert(LWLockHeldByMe(ProcArrayLock));
procArray->replication_slot_xmin = xmin;
procArray->replication_slot_catalog_xmin = catalog_xmin;
- if (!already_locked)
- LWLockRelease(ProcArrayLock);
-
elog(DEBUG1, "xmin required by slots: data %u, catalog %u",
xmin, catalog_xmin);
}
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index 99a58fb162..f25b8c1be3 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -91,7 +91,7 @@ extern void XidCacheRemoveRunningXids(TransactionId xid,
TransactionId latestXid);
extern void ProcArraySetReplicationSlotXmin(TransactionId xmin,
- TransactionId catalog_xmin, bool already_locked);
+ TransactionId catalog_xmin);
extern void ProcArrayGetReplicationSlotXmin(TransactionId *xmin,
TransactionId *catalog_xmin);