Skip to content

Commit 78cb246

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 0941aad commit 78cb246

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

src/backend/executor/nodeBitmapHeapscan.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,21 @@ BitmapHeapNext(BitmapHeapScanState *node)
185185
*/
186186
if (!scan)
187187
{
188-
bool need_tuples = false;
188+
bool need_tuples = true;
189189

190+
/*
191+
* Unfortunately it turns out that the below optimization does not
192+
* take the removal of TIDs by a concurrent vacuum into
193+
* account. The concurrent vacuum can remove dead TIDs and make
194+
* pages ALL_VISIBLE while those dead TIDs are referenced in the
195+
* bitmap. This would lead to a !need_tuples scan returning too
196+
* many tuples.
197+
*
198+
* In the back-branches, we therefore simply disable the
199+
* optimization. Removing all the relevant code would be too
200+
* invasive (and a major backpatching pain).
201+
*/
202+
#ifdef NOT_ANYMORE
190203
/*
191204
* We can potentially skip fetching heap pages if we do not need
192205
* any columns of the table, either for checking non-indexable
@@ -197,6 +210,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
197210
*/
198211
need_tuples = (node->ss.ps.plan->qual != NIL ||
199212
node->ss.ps.plan->targetlist != NIL);
213+
#endif
200214

201215
scan = table_beginscan_bm(node->ss.ss_currentRelation,
202216
node->ss.ps.state->es_snapshot,

0 commit comments

Comments
 (0)