Re: Introduce XID age based replication slot invalidation

From: Bharath Rupireddy <bharath(dot)rupireddyforpostgres(at)gmail(dot)com>
To: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
Cc: SATYANARAYANA NARLAPURAM <satyanarlapuram(at)gmail(dot)com>, "Hayato Kuroda (Fujitsu)" <kuroda(dot)hayato(at)fujitsu(dot)com>, John H <johnhyvr(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Introduce XID age based replication slot invalidation
Date: 2026-03-24 21:42:45
Message-ID: CALj2ACUmUb=CLEyfsQrW0WAkF6Y9fiBfG6pnPjepfOM7A1XReA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On Mon, Mar 23, 2026 at 4:36 PM Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> wrote:
>
> I've studied the discussion on this thread and the patch. I understand
> the purpose of this feature and agree that it's useful especially in
> cases where orphaned (physical or logical) replication slots prevent
> the xmin from advancing and inactive_since based slot invalidation
> might not fit.
>
> And +1 for treating both the slot's xmin and catalog_xmin similarly
> with the single GUC.

Thanks for reviewing the patch.

> > >> I made the following design choice: try invalidating only once per
> > >> vacuum cycle, not per table. While this keeps the cost of checking
> > >> (incl. the XidGenLock contention) for invalidation to a minimum when
> > >> there are a large number of tables and replication slots, it can be
> > >> less effective when individual tables/indexes are large. Invalidating
> > >> during checkpoints can help to some extent with the large table/index
> > >> cases. But I'm open to thoughts on this.
> > >
> > > It may not solve the intent when the vacuum cycle is longer, which one can expect on a large database particularly when there is heavy bloat.
> >
> > This design choice boils down to the following: a database instance
> > having either 1/ a large number of small tables or 2/ large tables.
> > From my experience, I have seen both cases but mostly case 2 (others
> > can correct me). In this context, having an XID age based slot
> > invalidation check once per relation makes sense. However, I'm open to
> > more thoughts here.
>
> ISTM that checking the XID-based slot invalidation per table would be
> more bullet-proof and cover many cases. How about checking the
> XID-based slot invalidation opportunity only when the OldestXmin is
> older than the new GUC? For example, we can do this check in
> heap_vacuum_rel() based on the VacuumCutoffs returned by
> vacuum_get_cutoffs(). If we invalidate at least one slot for its XID,
> we can re-compute the OldestXmin.

Agreed. Here's the patch that moves the XID-age based slot
invalidation check to vacuum_get_cutoffs. This has some nice
advantages: 1/ It makes the check once per table (to help with large
tables). 2/ It makes the check less costly since we rely on already
computed OldestXmin and nextXID values. 3/ It avoids the checkpointer
to do XID-age based slot invalidation which keeps the usage of this
GUC simple with no additional costs to the checkpointer - just the
vacuum (both vacuum command and autovacuum) does the invalidation when
needed.

I moved the new tests to the existing TAP test file
t/019_replslot_limit.pl alongside other invalidation tests.

I added detailed comments around InvalidateXIDAgedReplicationSlots and
slightly modified the docs.

Please find the v3 patch for further review.

PS: Thanks Sawada-san for the offlist chat.

--
Bharath Rupireddy
Amazon Web Services: https://aws.amazon.com

Attachment Content-Type Size
v3-0001-Add-XID-age-based-replication-slot-invalidation.patch application/octet-stream 25.5 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Nathan Bossart 2026-03-24 21:47:30 Re: Fixes inconsistent behavior in vacuum when it processes multiple relations
Previous Message Peter Eisentraut 2026-03-24 21:36:43 Re: Enable -Wstrict-prototypes and -Wold-style-definition by default