postgres.git / summary / log / commit / refs

commit    0557e1770230fe5ca855fdf45bb297bd38a9ec1b
Author:   Alvaro Herrera <alvherre@alvh.no-ip.org>
Date:     Tue Nov 22 09:56:07 2022 +0000
First released in: 16.0, 13.10, 14.7, 15.2

    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


src/backend/replication/slot.c | 7 +++++++ src/backend/storage/ipc/procarray.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index c036a2c37b6..899acfd912f 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -847,6 +847,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; @@ -854,8 +855,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 283517d9566..06918759e7c 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -3901,6 +3901,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); } /* [parent: 92daeca45df6]