From: | Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com> |
---|---|
To: | Sophie Alpert <pg(at)sophiebits(dot)com> |
Cc: | David Rowley <dgrowleyml(at)gmail(dot)com>, pgsql-hackers(at)lists(dot)postgresql(dot)org |
Subject: | Re: Fix missing EvalPlanQual recheck for TID scans |
Date: | 2025-09-11 05:30:20 |
Message-ID: | C901CB5D-7E79-4125-B310-C5A3052196A8@gmail.com |
Views: | Whole Thread | Raw Message | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
> On Sep 10, 2025, at 13:18, Chao Li <li(dot)evan(dot)chao(at)gmail(dot)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/
From | Date | Subject | |
---|---|---|---|
Next Message | Robins Tharakan | 2025-09-11 05:31:43 | Re: someone else to do the list of acknowledgments |
Previous Message | Shlok Kyal | 2025-09-11 05:30:02 | Re: issue with synchronized_standby_slots |