| 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-09-23 18:14:00 |
| Message-ID: | CALj2ACVRpA1UnZx=s0Ljsn01FcsEHEfj1mQXvQn69eO3Nq2YOA@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
On Fri, Aug 21, 2026 at 3:05 PM Bharath Rupireddy
<bharath(dot)rupireddyforpostgres(at)gmail(dot)com> wrote:
>
> Please find the attached v14 patches. 0003 now adds support for
> invalidating XID-aged synced replication slots on standbys.
Hi, while the discussion on invalidating the conflict detection slot
continues upthread, I made the following changes and attached the v15
patches.
I fixed an issue in the 0001 patch where the xid age invalidation used
a slot's persisted xmins, while it is the effective ones that hold
vacuum back. The patch now uses the effective xmins while deciding
whether to invalidate the slot. This covers all the cases where the
persisted and effective xmins differ. For example, a slot that is
still being created and holds the data xmin to export a snapshot has
data.xmin invalid while the effective value is set (added a test case
for this in 0001). Another is a logical or synced slot whose
catalog_xmin reaches disk before the effective value advances, so the
effective one still holds the previous, older xid.
On the concurrent repack side, I tested what happens to a repack slot
if it gets invalidated midway due to xid age. In this case, the slot
is temporary and holds an effective xmin along with the catalog xmin,
while its persisted xmin stays invalid. The decoding worker (i.e.
owner of the slot) gets signalled and terminated the usual way, and
the backend running concurrent repack then gets notified and fails
with an error. Since it is a temporary slot, the repack slot also gets
dropped when the worker gets terminated, so no leftover slot remains.
I didn't add a test for this as it doesn't bring new coverage.
Apart from the above, I self-reviewed all the patches and fixed many
things. Improved code comments, commit messages, docs, ensured the GUC
follows the rules prescribed in 977d865c36, moved the TAP tests into a
new file (099_invalidate_xid_aged_slots.pl for now to avoid patch
conflicts, will rename it to the next free number before the commit),
adjusted them to be simpler, deterministic and to use fewer resources
for the same coverage, ensured CI is happy, improved invalidation
messages, deduplicated common code, moved the replication slot release
in vacuum code after abort transaction, added variable annotations to
boolean params in the call sites, added a comment on top of
drop_local_obsolete_slots() on how xid-age invalidation can happen for
the synced slot on the standby while the primary's slot is valid
(review comment raised upthread), ran pgperltidy on TAP tests and many
more.
Thanks for reading this far. Please have a look at the attached v15 patches.
--
Bharath Rupireddy
Amazon Web Services: https://aws.amazon.com
| Attachment | Content-Type | Size |
|---|---|---|
| v15-0001-Invalidate-XID-aged-replication-slots.patch | application/x-patch | 30.1 KB |
| v15-0002-Allow-vacuum-to-invalidate-XID-aged-replication-.patch | application/x-patch | 29.7 KB |
| v15-0003-Invalidate-XID-aged-synced-replication-slots-on-.patch | application/x-patch | 10.1 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Robert Haas | 2026-09-23 18:20:49 | Re: pgsql: JSON_TABLE: propagate table-level ON ERROR to columns per SQL st |
| Previous Message | Marcos Pegoraro | 2026-09-23 18:13:39 | Re: [PATCH] Add pg_get_table_ddl() to reconstruct CREATE TABLE statements |