EPQ recheck across HashJoin, what does it actuall check? - Mailing list pgsql-hackers

From Kouhei Kaigai
Subject EPQ recheck across HashJoin, what does it actuall check?
Date
Msg-id 9A28C8860F777E439AA12E8AEA7694F8011DAA21@BPXM15GP.gisp.nec.co.jp
Whole thread Raw
List pgsql-hackers
Folks,

Could you correct me if I misunderstand the execution path.

We may have the following example. Query try to get row level locking
on the table 't1' that is under the 'Hash' node.

postgres=# EXPLAIN
postgres-# SELECT * FROM t0 NATURAL JOIN t1 WHERE ax between 10 and 30 FOR UPDATE OF t1;
         QUERY PLAN 
-------------------------------------------------------------------------------------------------LockRows
(cost=2682.53..263118.01rows=1980172 width=93)  ->  Hash Join  (cost=2682.53..243316.29 rows=1980172 width=93)
HashCond: (t0.aid = t1.aid)        ->  Seq Scan on t0  (cost=0.00..183332.58 rows=9999858 width=46)        ->  Hash
(cost=2435.00..2435.00rows=19802 width=51)              ->  Seq Scan on t1  (cost=0.00..2435.00 rows=19802 width=51)
               Filter: ((ax >= '10'::double precision) AND (ax <= '30'::double precision)) 
(7 rows)

Concurrent update on 't1' by other backend may kick EPQ recheck to ensure
whether the source tuple is still visible or not.
In this example, if somebody updated 't1.ax' to 45 concurrently, LockRows
shall discard the joined tuple and shall not acquire row lock.

ExecLockRows() fills up es_epqTuple[] slot by locked/non-locked tuples,
then calls EvalPlanQualNext() to re-evaluate the tuple.
EvalPlanQualNext() is a thin wrapper of ExecProcNode(), thus, it walks
down into the child plan nodes.

If it would be some kind of scan node, ExecScan() -> ExecScanFetch() handles
the EPQ recheck appropriately. Here is no matter.

In case of HashJoin, it seems to me ExecHashJoin() takes no special behavior.
If a record that has 't1.ax' = 20.0 when it was fetched and loaded to hash
table was updated to 45.0, it is ought to be handled as an invisible row.
However, ExecHashJoin() does not walk down to the inner side again, thus,
the updated tuple might be considered as visible, and locked.

If it would not be my oversight, ExecHashJoin() and ExecHash() needs to call
ExecProcNode() then re-evaluate its join condition again, apart from the
hash key values of the latest tuples.

Thought?

Thanks,
--
NEC Business Creation Division / PG-Strom Project
KaiGai Kohei <kaigai@ak.jp.nec.com>





pgsql-hackers by date:

Previous
From: Craig Ringer
Date:
Subject: Re: Re: [COMMITTERS] pgsql: Enable logical slots to follow timeline switches
Next
From: Andres Freund
Date:
Subject: Re: Timeline following for logical slots