| From: | Bharath Rupireddy <bharath(dot)rupireddyforpostgres(at)gmail(dot)com> |
|---|---|
| To: | Ashutosh Sharma <ashu(dot)coek88(at)gmail(dot)com> |
| Cc: | shveta malik <shveta(dot)malik(at)gmail(dot)com>, "Zhijie Hou (Fujitsu)" <houzj(dot)fnst(at)fujitsu(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, SATYANARAYANA NARLAPURAM <satyanarlapuram(at)gmail(dot)com>, Fujii Masao <masao(dot)fujii(at)gmail(dot)com>, vignesh C <vignesh21(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: [PATCH] Release replication slot on error in SQL-callable slot functions |
| Date: | 2026-08-06 19:20:12 |
| Message-ID: | CALj2ACW+z=_4536ENw1SPotGDSHX4PtASyhY67+pjZVYr-8wzA@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
On Thu, Aug 6, 2026 at 5:26 AM Ashutosh Sharma <ashu(dot)coek88(at)gmail(dot)com> wrote:
>
> > Please find the attached v9 patch.
>
> The patch looks good overall - just a few quick comments:
Thanks for taking a look at it.
> After releasing the slot in AtEOSubXact_ReplicationSlot(), I'd suggest
> adding these assertions:
>
> Assert(MyReplicationSlot == NULL);
> Assert(acquiredInSubId == InvalidSubTransactionId);
The slot release function sets MyReplicationSlot to NULL in both the
ephemeral and the other path, and clears acquiredInSubId with no early
return, so both conditions already hold there. I would prefer not to
add asserts that re-check what the release just above guarantees.
> + acquiredInSubId = GetCurrentSubTransactionId();
>
> Since the entire cleanup logic relies on the value of acquiredInSubId,
> should we make this more robust, something like:
>
> acquiredInSubId = IsTransactionState()
> ? GetCurrentSubTransactionId()
> : InvalidSubTransactionId;
I think it's redundant. When not in a transaction,
GetCurrentSubTransactionId already returns an invalid subxact ID (all
the commit and abort paths set it to invalid), so this check doesn't
add anything IMO.
> + if (isCommit)
> + {
> + acquiredInSubId = parentSubid;
> + return;
> + }
>
> Is there a test case covering this subtransaction handoff scenario? For example:
>
> DO $$
> BEGIN
> BEGIN
> PERFORM pg_replication_slot_advance('slot', some_valid_lsn);
> EXCEPTION WHEN division_by_zero THEN
> NULL;
> END;
>
> RAISE EXCEPTION 'outer failure';
> EXCEPTION WHEN OTHERS THEN
> NULL;
> END $$;
There can be the following cases:
1/ The inner subxact acquires the slot and the advance succeeds. It
releases the slot before returning, so there is no handoff.
2/ The advance errors out. Either the exception matches and the error
is caught, or it doesn't match and is re-thrown. In both cases the
slot is released when the inner subxact aborts, because PL/pgSQL rolls
back the subxact before checking for a matching handler. So by the
time a re-thrown error reaches the outer level, the slot is already
gone.
So the handoff branch is never reached today. It only fires if a
subxact commits while still holding a slot, which no slot function
does, since they all release before returning (see the discussion on
it upthread: https://www.postgresql.org/message-id/CALj2ACUD_K5zBgXD3ebYmhmouJx91fq%2BaiLeD8HSuC6xnYvj3g%40mail.gmail.com)
I realized the comment on the exception not matching needed some
adjustment. I made that change and attached the v10 patch.
BTW, here's the CF entry for this bug:
https://commitfest.postgresql.org/patch/7097/.
--
Bharath Rupireddy
Amazon Web Services: https://aws.amazon.com
| Attachment | Content-Type | Size |
|---|---|---|
| v10-0001-Fix-replication-slot-leak-on-error-caught-in-a-s.patch | application/octet-stream | 17.4 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Corey Huinker | 2026-08-06 19:48:41 | Re: Credits For v19 |
| Previous Message | Nazir Bilal Yavuz | 2026-08-06 19:05:03 | Re: Credits For v19 |