summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2022-11-22 10:56:07 +0100
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2022-11-22 10:56:07 +0100
commit36eeb37cd611c0a0bfb5743d9ddbef8f04fc87f3 (patch)
treeb7c02343061154d38b9a51a29ab0ff748cf21580
parent0e3215292f48f3e204402a07140322b63a30de36 (diff)
Ignore invalidated slots while computing oldest catalog Xmin
Once a logical slot has acquired a catalog_xmin, it doesn't let go of it, even when invalidated by exceeding the max_slot_wal_keep_size, which means that dead catalog tuples are not removed by vacuum anymore since the point is invalidated, until the slot is dropped. This could be catastrophic if catalog churn is high. Change the computation of Xmin to ignore invalidated slots, to prevent dead rows from accumulating. Backpatch to 13, where slot invalidation appeared. Author: Sirisha Chamarthi <sirichamarthi22@gmail.com> Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Discussion: https://postgr.es/m/CAKrAKeUEDeqquN9vwzNeG-CN8wuVsfRYbeOUV9qKO_RHok=j+g@mail.gmail.com
-rw-r--r--src/backend/replication/slot.c7
-rw-r--r--src/backend/storage/ipc/procarray.c3
2 files changed, 10 insertions, 0 deletions
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 02047ea9207..219d126d36d 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -766,6 +766,7 @@ ReplicationSlotsComputeRequiredXmin(bool already_locked)
ReplicationSlot *s = &ReplicationSlotCtl->replication_slots[i];
TransactionId effective_xmin;
TransactionId effective_catalog_xmin;
+ bool invalidated;
if (!s->in_use)
continue;
@@ -773,8 +774,14 @@ ReplicationSlotsComputeRequiredXmin(bool already_locked)
SpinLockAcquire(&s->mutex);
effective_xmin = s->effective_xmin;
effective_catalog_xmin = s->effective_catalog_xmin;
+ invalidated = (!XLogRecPtrIsInvalid(s->data.invalidated_at) &&
+ XLogRecPtrIsInvalid(s->data.restart_lsn));
SpinLockRelease(&s->mutex);
+ /* invalidated slots need not apply */
+ if (invalidated)
+ continue;
+
/* check the data xmin */
if (TransactionIdIsValid(effective_xmin) &&
(!TransactionIdIsValid(agg_xmin) ||
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 251ba9ebb9f..baad347eac1 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -3203,6 +3203,9 @@ ProcArraySetReplicationSlotXmin(TransactionId xmin, TransactionId catalog_xmin,
if (!already_locked)
LWLockRelease(ProcArrayLock);
+
+ elog(DEBUG1, "xmin required by slots: data %u, catalog %u",
+ xmin, catalog_xmin);
}
/*