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

From: shihao zhong <zhong950419(at)gmail(dot)com>
To: Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com>
Cc: Takeshi Ideriha <iderihatakeshi(at)gmail(dot)com>, 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 03:31:35
Message-ID: CAGRkXqRMvz-ZzC88_eXsyJZRpPXhE4_Fo6ueYdm5tpH+CHc6EQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

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:

s1: BEGIN; CREATE TABLE t (a int);
s1: SAVEPOINT sp; ALTER TABLE t ADD COLUMN b int; ROLLBACK TO sp;
s2: VACUUM FULL pg_class;
s1: COMMIT;

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

Thanks,
Shihao

Attachment Content-Type Size
v1-0001-Don-t-drop-a-live-tuple-when-its-successor-s-inse.patch application/octet-stream 2.2 KB
v1-0002-Add-a-test-for-CLUSTER-with-an-aborted-update.patch application/octet-stream 3.1 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message John Naylor 2026-10-19 05:02:57 Re: use-after-free in jsonb_set_lax()
Previous Message shihao zhong 2026-10-19 02:43:03 Re: BUG #19763: ManualBug2 NULL pointer dereference in make_build_data via examine_expression bypass of lookup_var_a