| From: | Takeshi Ideriha <iderihatakeshi(at)gmail(dot)com> |
|---|---|
| To: | 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-16 02:55:27 |
| Message-ID: | 41175da6-293f-4b8f-ad18-3636f3d8a2f6@gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
Hi
Thank you for reporting this.
>
> CLUSTER (and REPACK on master) silently drops a live row when the same
> transaction inserted the row and then updated it inside a subtransaction
> that was rolled back. No error is raised; the row is gone after COMMIT.
>
> CREATE TABLE t1(c0 int, c1 int);
> CREATE INDEX t1_i0 ON t1 (c1);
> BEGIN;
> INSERT INTO t1 VALUES (1, 1);
> SAVEPOINT s1; UPDATE t1 SET c0 = 2; ROLLBACK TO s1;
> CLUSTER t1 USING t1_i0;
> SELECT count(*) FROM t1; -- 0, expected 1
> COMMIT;
> SELECT count(*) FROM t1; -- 0, expected 1
>
While I was reproducing the bug, I noticed that if we SELECT rows before
CLUSTER, the issue won't happen. This suggests that not setting hint bit
is very likely to be related to the issue.
----
BEGIN;
INSERT INTO t1 VALUES (1, 1);
SAVEPOINT s1;
UPDATE t1 SET c0 = 2;
ROLLBACK TO s1;
SELECT count(*) FROM t1; -- SELECT before CLUSTER
CLUSTER VERBOSE t1 USING t1_i0;
SELECT count(*) FROM t1;
---
-- RESULT --
count
-------
1
(1 row)
INFO: repacking "public.t1" using index scan on "t1_i0"
INFO: "public.t1": found 0 removable, 1 nonremovable row versions in 1
pages
DETAIL: 0 dead row versions cannot be removed yet.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
CLUSTER
count
-------
1
(1 row)
COMMIT
count
-------
1
(1 row)
> REL_18_STABLE 4d62ef92fda. CLUSTER VERBOSE reports a
> negative "dead row versions cannot be removed yet" count (-1 here).
The value is tups_recently_dead in heapam_relation_copy_for_cluster().
tups_recently_dead decreases only when rewrite_heap_dead_tuple()
returnes TRUE in rewriteheap.c. I guess there is something wrong with
visibility check invloving hint bits in rewriteheap.c. I'll look into
this further.
Regards,
Takeshi Ideriha
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Manuel Reyes Bravo | 2026-10-16 03:28:59 | Re: use-after-free in jsonb_set_lax() |
| Previous Message | John Naylor | 2026-10-16 02:23:48 | Re: use-after-free in jsonb_set_lax() |