Skip to content

Commit 77d90d6

Browse files
committed
Remove HeapBitmapScan's skip_fetch optimization
The optimization does not take the removal of TIDs by a concurrent vacuum into account. The concurrent vacuum can remove dead TIDs and make pages ALL_VISIBLE while those dead TIDs are referenced in the bitmap. This can lead to a skip_fetch scan returning too many tuples. It likely would be possible to implement this optimization safely, but we don't have the necessary infrastructure in place. Nor is it clear that it's worth building that infrastructure, given how limited the skip_fetch optimization is. In the backbranches we just disable the optimization by always passing need_tuples=true to table_beginscan_bm(). We can't perform API/ABI changes in the backbranches and we want to make the change as minimal as possible. Author: Matthias van de Meent <boekewurm+postgres@gmail.com> Reported-By: Konstantin Knizhnik <knizhnik@garret.ru> Discussion: https://postgr.es/m/CAEze2Wg3gXXZTr6_rwC+s4-o2ZVFB5F985uUSgJTsECx6AmGcQ@mail.gmail.com Backpatch-through: 13
1 parent 2d6cfb0 commit 77d90d6

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

src/backend/executor/nodeBitmapHeapscan.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,20 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
742742
scanstate->shared_prefetch_iterator = NULL;
743743
scanstate->pstate = NULL;
744744

745+
/*
746+
* Unfortunately it turns out that the below optimization does not
747+
* take the removal of TIDs by a concurrent vacuum into
748+
* account. The concurrent vacuum can remove dead TIDs and make
749+
* pages ALL_VISIBLE while those dead TIDs are referenced in the
750+
* bitmap. This would lead to a !need_tuples scan returning too
751+
* many tuples.
752+
*
753+
* In the back-branches, we therefore simply disable the
754+
* optimization. Removing all the relevant code would be too
755+
* invasive (and a major backpatching pain).
756+
*/
757+
scanstate->can_skip_fetch = false;
758+
#ifdef NOT_ANYMORE
745759
/*
746760
* We can potentially skip fetching heap pages if we do not need any
747761
* columns of the table, either for checking non-indexable quals or for
@@ -751,6 +765,7 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
751765
*/
752766
scanstate->can_skip_fetch = (node->scan.plan.qual == NIL &&
753767
node->scan.plan.targetlist == NIL);
768+
#endif
754769

755770
/*
756771
* Miscellaneous initialization

0 commit comments

Comments
 (0)