This is an automated email from the ASF dual-hosted git repository. yjhjstz pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit 3062fe19c83f8d4b5cb949e326ef21638354586c Author: Alvaro Herrera <[email protected]> AuthorDate: Tue Nov 22 10:56:07 2022 +0100 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 <[email protected]> Reviewed-by: Ashutosh Bapat <[email protected]> Discussion: https://postgr.es/m/CAKrAKeUEDeqquN9vwzNeG-CN8wuVsfRYbeOUV9qKO_RHok=j...@mail.gmail.com (cherry picked from commit 36eeb37cd611c0a0bfb5743d9ddbef8f04fc87f3) --- src/backend/replication/slot.c | 7 +++++++ src/backend/storage/ipc/procarray.c | 3 +++ src/test/recovery/t/019_replslot_limit.pl | 1 + 3 files changed, 11 insertions(+) diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index dd2de9a69f..207985bae7 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -795,6 +795,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; @@ -802,8 +803,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 d56a5847da..f11c53242c 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -4886,6 +4886,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); } /* diff --git a/src/test/recovery/t/019_replslot_limit.pl b/src/test/recovery/t/019_replslot_limit.pl index be22ff1ea8..b365fcc886 100644 --- a/src/test/recovery/t/019_replslot_limit.pl +++ b/src/test/recovery/t/019_replslot_limit.pl @@ -48,6 +48,7 @@ $node_standby->append_conf('postgresql.conf', "primary_slot_name = 'rep1'"); $node_standby->start; +$node_primary->safe_psql('postgres', "CHECKPOINT;"); # Wait until standby has replayed enough data my $start_lsn = $node_primary->lsn('write'); $node_primary->wait_for_catchup($node_standby, 'replay', $start_lsn); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
