Fix race in Parallel Hash Join batch cleanup.
authorThomas Munro <[email protected]>
Wed, 17 Mar 2021 04:46:39 +0000 (17:46 +1300)
committerThomas Munro <[email protected]>
Wed, 17 Mar 2021 05:05:39 +0000 (18:05 +1300)
commit3b8981b6e1a2aea0f18384c803e21e9391de669a
tree512960ff7843b409c5031aaf5d47fb44020de258
parent37929599499fe5760a9dbab48a10a898879a0d44
Fix race in Parallel Hash Join batch cleanup.

With very unlucky timing and parallel_leader_participation off, PHJ
could attempt to access per-batch state just as it was being freed.
There was code intended to prevent that by checking for a cleared
pointer, but it was buggy.

Fix, by introducing an extra barrier phase.  The new phase
PHJ_BUILD_RUNNING means that it's safe to access the per-batch state to
find a batch to help with, and PHJ_BUILD_DONE means that it is too late.
The last to detach will free the array of per-batch state as before, but
now it will also atomically advance the phase at the same time, so that
late attachers can avoid the hazard, without the data race.  This
mirrors the way per-batch hash tables are freed (see phases
PHJ_BATCH_PROBING and PHJ_BATCH_DONE).

Revealed by a one-off build farm failure, where BarrierAttach() failed a
sanity check assertion, because the memory had been clobbered by
dsa_free().

Back-patch to 11, where the code arrived.

Reported-by: Michael Paquier <[email protected]>
Discussion: https://postgr.es/m/20200929061142.GA29096%40paquier.xyz
src/backend/executor/nodeHash.c
src/backend/executor/nodeHashjoin.c
src/include/executor/hashjoin.h