Re: Introduce XID age based replication slot invalidation

From: Bharath Rupireddy <bharath(dot)rupireddyforpostgres(at)gmail(dot)com>
To: Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Srinath Reddy Sadipiralla <srinath2133(at)gmail(dot)com>, 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-08-13 00:00:00
Message-ID: CALj2ACXO6=35QSO2CSSCi2qSODCon8VLBZuB3YyXw3bkd1Pk-w@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On Tue, Aug 11, 2026 at 7:00 AM Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> wrote:
>
> Checking 0001 patch, I noticed:
>
> + * 3. The slot is not being synced from the primary while the server is in
> + * recovery. This is because synced slots are always considered to be
> + * inactive because they don't perform logical decoding to produce changes.
> + */
> +static inline bool
> +CanInvalidateXidAgedSlot(ReplicationSlot *s)
> ...
>
> This seems to mimic the comments from CanInvalidateIdleSlot() which I
> think is not correct. Because inactive_since for synced slots on
> standby has no meaning as we don't allow decoding from them so they
> are always inactive but I think the same is not true for their xmin
> values. Even if we want to follow the core logic of idle slots, the
> comments should reflect the actual cause. I feel in this case we want
> to mostly rely on corresponding primary slots such that when they get
> invalidated, we will sync those and invalidate synced slots.

Thanks Amit for looking at it. Yes, the description is not correct.
TBH I hadn't thought much about synced slots, so this was a good push
to dive deep. Please find my overall take on this below.

> One more thing we should consider is that synced slot's xmin can lead
> to holding back xmin of primary due to hot_standby_feedback mechanism
> in some cases when the sync interval is longer

I can think of the following reasons (unless I'm missing others) where
the standby's synced slot's catalog_xmin can hold back vacuum
(catalog's dead rows and XIDs) on the primary, and they seem to be
easily reproducible (I attached a TAP test):

1/ Slot sync worker stuck or erroring: the synced slot's catalog_xmin
is old and gets sent onto the physical slot on the primary via HS
feedback.
2/ Slot sync worker is off with rare/missing/forgotten manual syncs:
the synced slot's catalog_xmin is old and gets sent onto the physical
slot on the primary via HS feedback.
3/ Long HS feedback interval: the synced slot's catalog_xmin is
current but its new value isn't reported, so the physical slot on the
primary keeps the old catalog_xmin.

> whereas there is no
> such possibility w.r.t WAL,

Yes, this is unlike WAL, which a synced slot holds only on the
standby. Its catalog_xmin holds up resources (dead rows and XIDs) on
the primary.

> so is it okay to keep the same behaviour
> for both max_slot_xid_age and idle_replication_slot_timeout w.r.t
> synced slots? I am not sure if this is a real risk or just a
> theoretical possibility but wanted to bring it to your attention so
> that we can consider it.

I believe this can happen in practice (as explained above). IMHO, XID
age based slot invalidation must invalidate the synced slot on the
standby (just like other invalidations except the idle-timeout based)
if its catalog_xmin is aged and blocking vacuum on the primary.

Thoughts?

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

Attachment Content-Type Size
nocfbot_100_synced_slot_catalog_vacuum.pl text/x-perl-script 10.4 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Tatsuya Kawata 2026-08-13 00:26:05 Re: [PATCH] Remove stale comment and dead store in BuildTupleHashTable
Previous Message Michael Paquier 2026-08-12 22:56:37 Re: LibreSSL and OpenSSL separation in libpq to support 1.1.1 deprecation