Re: [PATCH] Release replication slot on error in SQL-callable slot functions

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-08 21:17:00
Message-ID: CALj2ACU-mVxrak_Q0EP1sZg8h=7pg1d09Gj6Ody5jH6zxiZQLA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On Fri, Aug 7, 2026 at 4:31 AM Ashutosh Sharma <ashu(dot)coek88(at)gmail(dot)com> wrote:
>
> + if (MyReplicationSlot != NULL)
> + ReplicationSlotRelease();
>
> From this if-condition in AtEOSubXact_ReplicationSlot(), it appears
> that even when 'acquiredInSubId == mySubid', 'MyReplicationSlot' could
> be NULL and if that ever happens we may/will return from this function
> without clearing 'acquiredInSubId'. That matters because
> 'currentSubTransactionId' is reset to TopSubTransactionId at each
> StartTransaction(), so subxact ids are reused across top-level
> transactions; a stale id left behind here could later match an
> unrelated subxact.
>
> AFAIU, in practice this should be unreachable: 'acquiredInSubId' is
> only ever set together with 'MyReplicationSlot', and both
> ReplicationSlotRelease() and ReplicationSlotDropAcquired() clear it,
> so "MyReplicationSlot == NULL" implies "acquiredInSubId ==
> InvalidSubTransactionId", which can never equal a real `mySubid`. But
> the guard's existence suggests you think "MyReplicationSlot == NULL"
> is possible.
>
> So either the reasoning above deserves a comment atop the
> if-condition, or, if the NULL case really is impossible, an
> 'Assert(MyReplicationSlot != NULL)' would document it more directly
> than a silent 'if'.

I get your point. Would something like the below work?

+ /*
+ * The aborting subxact is the one that acquired the slot, and its id is
+ * never invalid, so acquiredInSubId is valid here. It is set only when a
+ * slot is held, and cleared when the slot is released, so the slot must
+ * still be held.
+ */
+ Assert(acquiredInSubId != InvalidSubTransactionId);
+ Assert(MyReplicationSlot != NULL);
+ ReplicationSlotRelease();

I removed the unnecessary header file inclusions (review comment from
Shveta upthread) and attached the v11 patch.

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

Attachment Content-Type Size
v11-0001-Fix-replication-slot-leak-on-error-caught-in-a-s.patch application/octet-stream 17.0 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tomas Vondra 2026-08-08 22:08:44 Re: Is there value in having optimizer stats for joins/foreignkeys?
Previous Message Jelte Fennema-Nio 2026-08-08 20:57:55 Re: WAL compression setting after PostgreSQL LZ4 default change