On Wed, Sep 23, 2026 at 11:44 PM Bharath Rupireddy <[email protected]> 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. [1] https://www.postgresql.org/message-id/CALj2ACWTz5fKMPa0wNghRFdfPBzc%2Bj3x%2BkcXSeCo%2B3twZmDdyg%40mail.gmail.com -- Thanks, Nisha
