Re: BUG #19760: CLUSTER loses a row the transaction inserted and then updated in a rolled-back subtransaction

From: Takeshi Ideriha <iderihatakeshi(at)gmail(dot)com>
To: shihao zhong <zhong950419(at)gmail(dot)com>, Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com>
Cc: alpkeles99(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #19760: CLUSTER loses a row the transaction inserted and then updated in a rolled-back subtransaction
Date: 2026-10-19 05:15:35
Message-ID: 5fff280b-96c4-497f-bbfc-0af95b9844b3@gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi Shihao, Ayush

On 2026/10/19 12:31, shihao zhong wrote:
> Hi,
>
> Here is a patch. rewrite_heap_dead_tuple() drops the held tuple when its
> successor is dead, but that is only right if the successor's inserter
> committed. If it aborted, the update never happened, so 0001 keeps the
> tuple and adds its logical rewrite mapping.

> Setting the hint in HeapTupleSatisfiesVacuum() is not enough. VACUUM
> FULL on a catalog can see a transaction that is still open, and this
> loses the pg_class row of a committed table:
I was actually also writing a code to fix the issue and have just
noticed the patch was already submitted. Attached a patch for reference.
I haven't considered into logical_rewrite_heap_tuple(). I need to check
this... Thank you.

> {
>+ /*
>+ * If the inserter of this tuple aborted, the update >never happened
>+ * and the earlier tuple is not dead. It will be >written at the end.
>+ */
>+ if (!HeapTupleHeaderXminCommitted(old_tuple->t_data) &&
>+ !>TransactionIdDidCommit(HeapTupleHeaderGetXmin(old_tuple->t_data)))
>+ return false;

I am thinking like the below since HeapTupleSatisfiesVacuum set the xmin
invalid hint bit for the dead tuple. So I believe we can just rely on
HeapTupleHeaderXminInvalid hint bit.

+ if (HeapTupleHeaderXminInvalid(old_tuple->t_data))
+ return false;

What do you think above?

>0002 is an isolation test for that case, it is optional. But I want it
>in tree to prevent
>future regression in that area.

+1. I also think this is optional but I believe the issue is easy to
oversight, so adding a new test would be helpful.

Regards,
Takeshi Ideriha

Attachment Content-Type Size
v1-0001-fix-cluster-misses-a-live-tuple-updated-by-subtra.patch text/plain 2.3 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Staroverov Ilja 2026-10-19 05:16:42 Re: pg_stat_statements replaces SQL/JSON ON EMPTY / ON ERROR keywords with parameters
Previous Message John Naylor 2026-10-19 05:02:57 Re: use-after-free in jsonb_set_lax()