Re: Fix missing EvalPlanQual recheck for TID scans
Chao Li <li.evan.chao@gmail.com>
From: Chao Li <li.evan.chao@gmail.com>
To: Sophie Alpert <pg@sophiebits.com>
Cc: David Rowley <dgrowleyml@gmail.com>,
pgsql-hackers@lists.postgresql.org
Date: 2025-09-11T05:30:20Z
Lists: pgsql-hackers
> On Sep 10, 2025, at 13:18, Chao Li <li.evan.chao@gmail.com> wrote: > > With my proposal, my theory is that, TidNext() fetches a tuple by ctid, if other concurrent transaction update/delete the tuple, the tuple's visibility changes. > I did some more debugging on this issue today, and I withdraw my previous proposal of checking visibility. I can confirm that, every time when TidRecheck() is called, “node” is brand new, so the current patch do duplicately calculate TidListEval(). But, why can't we make TidRecheck() to simplify return FALSE? Looks like the only case where TidRecheck() is called is a concurrent transaction upadated the row, and in that case, ctid have must be changed. The following case WON’T call TidRecheck(): Case 1. Concurrent delete ===== S1: Begin; delete t where ctid = ‘(0,1)’ S2: Update t set something where ctid = ‘(0,1)’; // block S1: Commit; S2 will just fail to update the row because the row has been deleted by s1. Case 2: select for update/share ====== S1: Begin; Select * from t where ctid = ‘(0,1)’ for share; S2: Update t set something where ctid = ‘(0,1)’; // block S1: Commit; S2 will just successfully update the row, because s1 release the lock and the row is still there. Case 3: join update ====== S1: Begin; Update t2 set something where id = 1; S2: Update t2 set something where id = (select id from t where ctid = ‘(0, 1)’); // block S1: commit S2 will successfully update t2’s row. In this process, index scan’t recheck against t2 will be called, TidRecheck() against t will not be called. ====== Unless I missed some cases, we can simply return FALSE from TidRecheck(). Best regards, -- Chao Li (Evan) HighGo Software Co., Ltd. https://www.highgo.com/
Commits
-
Add missing EPQ recheck for TID Range Scan
- f78a69034740 14.20 landed
- f00ad440a5b6 15.15 landed
- ba0203880a8f 16.11 landed
- 0fb06e893331 17.7 landed
- 78e6047dcea5 18.0 landed
- ac06ea8f7b6c 19 (unreleased) landed
-
Add missing EPQ recheck for TID Scan
- 940f3cd5df57 13.23 landed
- 2eb7ea97d8af 14.20 landed
- 005770203889 15.15 landed
- d6539f88b7c5 16.11 landed
- 3d939a9b1c72 17.7 landed
- bae6c74ba4e4 18.0 landed
- dee21ea6d617 19 (unreleased) landed
-
Repair problems with EvalPlanQual where target table is scanned as
- 6799a6ca21e5 7.2.1 cited
-
Tid access method feature from Hiroshi Inoue, Inoue@tpf.co.jp
- 6f9ff92cc0ff 7.1.1 cited