| From: | Nisha Moond <nisha(dot)moond412(at)gmail(dot)com> |
|---|---|
| To: | Bharath Rupireddy <bharath(dot)rupireddyforpostgres(at)gmail(dot)com> |
| Cc: | Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, 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-10-06 11:48:59 |
| Message-ID: | CABdArM48J96RfZYnfwWr-ptt4UsEAV8fjFNWxV22PcWp+s-cgQ@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Wed, Sep 23, 2026 at 11:44 PM Bharath Rupireddy
<bharath(dot)rupireddyforpostgres(at)gmail(dot)com> wrote:
>
>
> Thanks for reading this far. Please have a look at the attached v15 patches.
>
Thanks for the updated patches.
- v15-0001 fails to apply on HEAD and needs to be rebased after commit 46024c5.
1) I observed an issue:
With v15, an aged failover slot also gets the standby's physical slot
invalidated on the primary. This behavior was also mentioned
upthread[1].
The standby forwards the synced copy's catalog_xmin through
hot_standby_feedback, so the physical slot carries a catalog_xmin ≤
the failover slot's. The primary's checkpoint then invalidates both in
the same pass.
I reproduced this with max_slot_xid_age = 100 on the primary (0 on the
standby) and the failover subscription disabled. The physical slot was
invalidated for its catalog xmin age while its xmin age was 0, and the
standby now loops on "can no longer access replication slot":
slot_name | slot_type | active | xmin | catalog_xmin | xmin_age |
cxmin_age | invalidation_reason
-----------+-----------+--------+------+--------------+----------+-----------+---------------------
standby_1 | physical | t | 968 | 667 | 0 | 301 |
sub1 | logical | f | | 667 | | 301 |
CHECKPOINT;
standby_1 | physical | f | 968 | 667 | 0 |
301 | xid_aged
sub1 | logical | f | | 667 | |
301 | xid_aged
With the GUC also set on the standby, 0003 can avoid this only if the
standby's restartpoint happens to invalidate the synced copy before
the primary's checkpoint runs.
IMO, the impact seems high for the cause:
- the standby loses streaming and WAL retention, and needs manual
action; it may even need a rebuild once the WAL is gone
- with the slot in synchronized_standby_slots, other failover slots
on the primary would also stall
- for synced slots it gains nothing: the failover slot is invalidated
anyway, and the next sync would release the catalog_xmin
Given the impact, I feel this should be handled.
IIUC, the same would also happen for a lagging or abandoned logical
slot owned by the standby.
The difficulty I see is that the primary sees only one catalog_xmin
per physical slot. It can't tell whether the value comes from a synced
copy that will resolve itself, or from a lagging or abandoned slot
owned by the standby, which shouldn't be allowed to pin the primary's
catalog horizon indefinitely.
But it may not need to tell. Instead of invalidating the physical
slot, the primary could ignore an aged catalog_xmin in the feedback
and clear one already stored, so the slot stays valid. Vacuum can then
remove those catalog rows, and the standby's existing
recovery-conflict handling invalidates the slots that needed them as
"rows_removed". Those rows are lost with the current behaviour too,
once the physical slot is invalidated; this way the standby just stays
connected.
The downsides I see: hot_standby_feedback's protection becomes bounded
by the primary's max_slot_xid_age, but that's no different from now,
where the standby loses its connection at the same bound. Also, the
slots on the standby show "rows_removed" as the invalidation reason,
though the underlying cause was the catalog_xmin age on the primary.
Thoughts?
~~~
2) One minor comment on 001:
+++ b/doc/src/sgml/system-views.sgml
...
+ <literal>xmin</literal> or <literal>catalog_xmin</literal>
+ has reached the transaction age specified by
...
I think we should use "has exceeded" instead of "has reached" for
better clarity.
--
Thanks,
Nisha
| From | Date | Subject | |
|---|---|---|---|
| Next Message | John Naylor | 2026-10-06 11:49:02 | Re: Improving scalability of Parallel Bitmap Heap/Index Scan |
| Previous Message | Matthias van de Meent | 2026-10-06 11:48:57 | Re: Exploring pass-by-value for small Bitmapset sets |