agora inbox for [email protected]
help / color / mirror / Atom feedFrom: Melanie Plageman <[email protected]>
Subject: [PATCH v19 19/21] Push BitmapHeapScan prefetch code into heap AM
Date: Sat, 6 Apr 2024 16:21:04 -0400
An earlier commit eliminated a table AM layering violation for the
current block in a BitmapHeapScan but left the violation in
BitmapHeapScan prefetching code.
To resolve this, move and manage all state used for prefetching entirely
into the heap AM.
Author: Melanie Plageman
Discussion: https://postgr.es/m/CAAKRu_ZwCwWFeL_H3ia26bP2e7HiKLWt0ZmGXPVwPO6uXq0vaA%40mail.gmail.com
---
src/backend/access/heap/heapam.c | 38 ++++++-
src/backend/access/heap/heapam_handler.c | 125 +++++++++++++++-------
src/backend/executor/nodeBitmapHeapscan.c | 97 +++--------------
src/include/access/heapam.h | 29 ++++-
src/include/access/tableam.h | 18 +---
src/include/nodes/execnodes.h | 12 ---
6 files changed, 167 insertions(+), 152 deletions(-)
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index a45fdb50285..71f93bfbb1d 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -1065,6 +1065,14 @@ heap_beginscan_bm(Relation relation, Snapshot snapshot, uint32 flags)
scan->vmbuffer = InvalidBuffer;
scan->empty_tuples_pending = 0;
+ /*
+ * The rest of the BitmapHeapScanDesc members related to prefetching will
+ * be initialized in heap_rescan_bm().
+ */
+ scan->pvmbuffer = InvalidBuffer;
+ scan->prefetch_iterator.serial = NULL;
+ scan->prefetch_iterator.parallel = NULL;
+
return (TableScanDesc) scan;
}
@@ -1108,7 +1116,8 @@ heap_rescan(TableScanDesc sscan, ScanKey key, bool set_params,
void
heap_rescan_bm(TableScanDesc sscan, TIDBitmap *tbm,
- ParallelBitmapHeapState *pstate, dsa_area *dsa)
+ ParallelBitmapHeapState *pstate, dsa_area *dsa,
+ int prefetch_maximum)
{
BitmapHeapScanDesc scan = (BitmapHeapScanDesc) sscan;
@@ -1122,6 +1131,17 @@ heap_rescan_bm(TableScanDesc sscan, TIDBitmap *tbm,
scan->empty_tuples_pending = 0;
unified_tbm_end_iterate(&scan->iterator);
+ if (BufferIsValid(scan->pvmbuffer))
+ ReleaseBuffer(scan->pvmbuffer);
+
+ unified_tbm_end_iterate(&scan->prefetch_iterator);
+
+ scan->prefetch_maximum = prefetch_maximum;
+ scan->pstate = pstate;
+ scan->prefetch_target = -1;
+ scan->prefetch_pages = 0;
+ scan->pfblockno = InvalidBlockNumber;
+
/*
* reinitialize heap scan descriptor
*/
@@ -1131,6 +1151,17 @@ heap_rescan_bm(TableScanDesc sscan, TIDBitmap *tbm,
pstate ?
pstate->tbmiterator :
InvalidDsaPointer);
+
+#ifdef USE_PREFETCH
+ if (prefetch_maximum > 0)
+ {
+ unified_tbm_begin_iterate(&scan->prefetch_iterator, tbm, dsa,
+ pstate ?
+ pstate->prefetch_iterator :
+ InvalidDsaPointer);
+ }
+#endif /* USE_PREFETCH */
+
}
@@ -1183,6 +1214,11 @@ heap_endscan_bm(TableScanDesc sscan)
unified_tbm_end_iterate(&scan->iterator);
+ if (BufferIsValid(scan->pvmbuffer))
+ ReleaseBuffer(scan->pvmbuffer);
+
+ unified_tbm_end_iterate(&scan->prefetch_iterator);
+
/*
* decrement relation reference count and free scan descriptor storage
*/
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index 85564fef2e0..77888cdc90d 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -60,6 +60,9 @@ static bool SampleHeapTupleVisible(TableScanDesc scan, Buffer buffer,
OffsetNumber tupoffset);
static BlockNumber heapam_scan_get_blocks_done(HeapScanDesc hscan);
+static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanDesc scan);
+static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanDesc scan);
+static inline void BitmapPrefetch(BitmapHeapScanDesc scan);
static const TableAmRoutine heapam_methods;
@@ -2187,26 +2190,26 @@ heapam_estimate_rel_size(Relation rel, int32 *attr_widths,
* iterator in prefetch_pages. For each block the main iterator returns, we
* decrement prefetch_pages.
*/
-void
-BitmapAdjustPrefetchIterator(BitmapHeapScanState *node)
+static inline void
+BitmapAdjustPrefetchIterator(BitmapHeapScanDesc scan)
{
#ifdef USE_PREFETCH
- ParallelBitmapHeapState *pstate = node->pstate;
- UnifiedTBMIterator *prefetch_iterator = &node->prefetch_iterator;
+ ParallelBitmapHeapState *pstate = scan->pstate;
+ UnifiedTBMIterator *prefetch_iterator = &scan->prefetch_iterator;
TBMIterateResult *tbmpre;
if (pstate == NULL)
{
- if (node->prefetch_pages > 0)
+ if (scan->prefetch_pages > 0)
{
/* The main iterator has closed the distance by one page */
- node->prefetch_pages--;
+ scan->prefetch_pages--;
}
else if (!prefetch_iterator->exhausted)
{
/* Do not let the prefetch iterator get behind the main one */
tbmpre = unified_tbm_iterate(prefetch_iterator);
- node->pfblockno = tbmpre ? tbmpre->blockno : InvalidBlockNumber;
+ scan->pfblockno = tbmpre ? tbmpre->blockno : InvalidBlockNumber;
}
return;
}
@@ -2220,7 +2223,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node)
* Note that moving the call site of BitmapAdjustPrefetchIterator()
* exacerbates the effects of this bug.
*/
- if (node->prefetch_maximum > 0)
+ if (scan->prefetch_maximum > 0)
{
SpinLockAcquire(&pstate->mutex);
if (pstate->prefetch_pages > 0)
@@ -2244,7 +2247,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node)
if (!prefetch_iterator->exhausted)
{
tbmpre = unified_tbm_iterate(prefetch_iterator);
- node->pfblockno = tbmpre ? tbmpre->blockno : InvalidBlockNumber;
+ scan->pfblockno = tbmpre ? tbmpre->blockno : InvalidBlockNumber;
}
}
}
@@ -2259,33 +2262,33 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node)
* page/tuple, then to one after the second tuple is fetched, then
* it doubles as later pages are fetched.
*/
-void
-BitmapAdjustPrefetchTarget(BitmapHeapScanState *node)
+static inline void
+BitmapAdjustPrefetchTarget(BitmapHeapScanDesc scan)
{
#ifdef USE_PREFETCH
- ParallelBitmapHeapState *pstate = node->pstate;
+ ParallelBitmapHeapState *pstate = scan->pstate;
if (pstate == NULL)
{
- if (node->prefetch_target >= node->prefetch_maximum)
+ if (scan->prefetch_target >= scan->prefetch_maximum)
/* don't increase any further */ ;
- else if (node->prefetch_target >= node->prefetch_maximum / 2)
- node->prefetch_target = node->prefetch_maximum;
- else if (node->prefetch_target > 0)
- node->prefetch_target *= 2;
+ else if (scan->prefetch_target >= scan->prefetch_maximum / 2)
+ scan->prefetch_target = scan->prefetch_maximum;
+ else if (scan->prefetch_target > 0)
+ scan->prefetch_target *= 2;
else
- node->prefetch_target++;
+ scan->prefetch_target++;
return;
}
/* Do an unlocked check first to save spinlock acquisitions. */
- if (pstate->prefetch_target < node->prefetch_maximum)
+ if (pstate->prefetch_target < scan->prefetch_maximum)
{
SpinLockAcquire(&pstate->mutex);
- if (pstate->prefetch_target >= node->prefetch_maximum)
+ if (pstate->prefetch_target >= scan->prefetch_maximum)
/* don't increase any further */ ;
- else if (pstate->prefetch_target >= node->prefetch_maximum / 2)
- pstate->prefetch_target = node->prefetch_maximum;
+ else if (pstate->prefetch_target >= scan->prefetch_maximum / 2)
+ pstate->prefetch_target = scan->prefetch_maximum;
else if (pstate->prefetch_target > 0)
pstate->prefetch_target *= 2;
else
@@ -2298,18 +2301,19 @@ BitmapAdjustPrefetchTarget(BitmapHeapScanState *node)
/*
* BitmapPrefetch - Prefetch, if prefetch_pages are behind prefetch_target
*/
-void
-BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
+static inline void
+BitmapPrefetch(BitmapHeapScanDesc scan)
{
#ifdef USE_PREFETCH
- ParallelBitmapHeapState *pstate = node->pstate;
- UnifiedTBMIterator *prefetch_iterator = &node->prefetch_iterator;
+ ParallelBitmapHeapState *pstate = scan->pstate;
+ Relation rel = scan->heap_common.rs_base.rs_rd;
+ UnifiedTBMIterator *prefetch_iterator = &scan->prefetch_iterator;
if (pstate == NULL)
{
if (!prefetch_iterator->exhausted)
{
- while (node->prefetch_pages < node->prefetch_target)
+ while (scan->prefetch_pages < scan->prefetch_target)
{
TBMIterateResult *tbmpre = unified_tbm_iterate(prefetch_iterator);
bool skip_fetch;
@@ -2320,8 +2324,8 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
unified_tbm_end_iterate(prefetch_iterator);
break;
}
- node->prefetch_pages++;
- node->pfblockno = tbmpre->blockno;
+ scan->prefetch_pages++;
+ scan->pfblockno = tbmpre->blockno;
/*
* If we expect not to have to actually read this heap page,
@@ -2329,14 +2333,14 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
* logic normally. (Would it be better not to increment
* prefetch_pages?)
*/
- skip_fetch = (!(scan->rs_flags & SO_NEED_TUPLES) &&
+ skip_fetch = (!(scan->heap_common.rs_base.rs_flags & SO_NEED_TUPLES) &&
!tbmpre->recheck &&
- VM_ALL_VISIBLE(node->ss.ss_currentRelation,
+ VM_ALL_VISIBLE(rel,
tbmpre->blockno,
- &node->pvmbuffer));
+ &scan->pvmbuffer));
if (!skip_fetch)
- PrefetchBuffer(scan->rs_rd, MAIN_FORKNUM, tbmpre->blockno);
+ PrefetchBuffer(rel, MAIN_FORKNUM, tbmpre->blockno);
}
}
@@ -2376,17 +2380,17 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
break;
}
- node->pfblockno = tbmpre->blockno;
+ scan->pfblockno = tbmpre->blockno;
/* As above, skip prefetch if we expect not to need page */
- skip_fetch = (!(scan->rs_flags & SO_NEED_TUPLES) &&
+ skip_fetch = (!(scan->heap_common.rs_base.rs_flags & SO_NEED_TUPLES) &&
!tbmpre->recheck &&
- VM_ALL_VISIBLE(node->ss.ss_currentRelation,
+ VM_ALL_VISIBLE(rel,
tbmpre->blockno,
- &node->pvmbuffer));
+ &scan->pvmbuffer));
if (!skip_fetch)
- PrefetchBuffer(scan->rs_rd, MAIN_FORKNUM, tbmpre->blockno);
+ PrefetchBuffer(rel, MAIN_FORKNUM, tbmpre->blockno);
}
}
}
@@ -2419,6 +2423,8 @@ heapam_scan_bitmap_next_block(TableScanDesc sscan,
*blockno = InvalidBlockNumber;
*recheck = true;
+ BitmapAdjustPrefetchIterator(scan);
+
do
{
CHECK_FOR_INTERRUPTS();
@@ -2559,6 +2565,19 @@ heapam_scan_bitmap_next_block(TableScanDesc sscan,
else
(*exact_pages)++;
+
+ /*
+ * If serial, we can error out if the the prefetch block doesn't stay
+ * ahead of the current block.
+ */
+ if (scan->pstate == NULL &&
+ !scan->prefetch_iterator.exhausted &&
+ scan->pfblockno < block)
+ elog(ERROR, "prefetch and main iterators are out of sync");
+
+ /* Adjust the prefetch target */
+ BitmapAdjustPrefetchTarget(scan);
+
/*
* Return true to indicate that a valid block was found and the bitmap is
* not exhausted. If there are no visible tuples on this page,
@@ -2595,6 +2614,36 @@ heapam_scan_bitmap_next_tuple(TableScanDesc sscan,
if (hscan->rs_cindex < 0 || hscan->rs_cindex >= hscan->rs_ntuples)
return false;
+#ifdef USE_PREFETCH
+
+ /*
+ * Try to prefetch at least a few pages even before we get to the second
+ * page if we don't stop reading after the first tuple.
+ */
+ if (!scan->pstate)
+ {
+ if (scan->prefetch_target < scan->prefetch_maximum)
+ scan->prefetch_target++;
+ }
+ else if (scan->pstate->prefetch_target < scan->prefetch_maximum)
+ {
+ /* take spinlock while updating shared state */
+ SpinLockAcquire(&scan->pstate->mutex);
+ if (scan->pstate->prefetch_target < scan->prefetch_maximum)
+ scan->pstate->prefetch_target++;
+ SpinLockRelease(&scan->pstate->mutex);
+ }
+
+ /*
+ * We issue prefetch requests *after* fetching the current page to try to
+ * avoid having prefetching interfere with the main I/O. Also, this should
+ * happen only when we have determined there is still something to do on
+ * the current page, else we may uselessly prefetch the same page we are
+ * just about to request for real.
+ */
+ BitmapPrefetch(scan);
+#endif /* USE_PREFETCH */
+
targoffset = hscan->rs_vistuples[hscan->rs_cindex];
page = BufferGetPage(hscan->rs_cbuf);
lp = PageGetItemId(page, targoffset);
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index fda5645e4ae..11945ab9c42 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -69,7 +69,6 @@ BitmapHeapNext(BitmapHeapScanState *node)
TIDBitmap *tbm;
TupleTableSlot *slot;
ParallelBitmapHeapState *pstate = node->pstate;
- dsa_area *dsa = node->ss.ps.state->es_query_dsa;
/*
* extract necessary information from index scan node
@@ -93,7 +92,9 @@ BitmapHeapNext(BitmapHeapScanState *node)
*/
if (!node->initialized)
{
+ Relation rel = node->ss.ss_currentRelation;
bool need_tuples = false;
+ int prefetch_maximum = 0;
/*
* The leader will immediately come out of the function, but others
@@ -103,6 +104,14 @@ BitmapHeapNext(BitmapHeapScanState *node)
bool init_shared_state = node->pstate ?
BitmapShouldInitializeSharedState(node->pstate) : false;
+ /*
+ * Maximum number of prefetches for the tablespace if configured,
+ * otherwise the current value of the effective_io_concurrency GUC.
+ */
+#ifdef USE_PREFETCH
+ prefetch_maximum = get_tablespace_io_concurrency(rel->rd_rel->reltablespace);
+#endif
+
/*
* Only serial bitmap table scans and the parallel leader in a
* parallel bitmap table scan should build the bitmap.
@@ -124,7 +133,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
*/
pstate->tbmiterator = tbm_prepare_shared_iterate(tbm);
#ifdef USE_PREFETCH
- if (node->prefetch_maximum > 0)
+ if (prefetch_maximum > 0)
{
pstate->prefetch_iterator =
tbm_prepare_shared_iterate(tbm);
@@ -154,22 +163,13 @@ BitmapHeapNext(BitmapHeapScanState *node)
node->ss.ss_currentRelation,
node->ss.ps.state->es_snapshot,
need_tuples,
+ prefetch_maximum,
node->tbm,
node->pstate,
node->ss.ps.state->es_query_dsa);
node->ss.ss_currentScanDesc = scan;
-#ifdef USE_PREFETCH
- if (node->prefetch_maximum > 0)
- {
- unified_tbm_begin_iterate(&node->prefetch_iterator, tbm, dsa,
- pstate ?
- pstate->prefetch_iterator :
- InvalidDsaPointer);
- }
-#endif /* USE_PREFETCH */
-
node->initialized = true;
goto new_page;
@@ -185,37 +185,6 @@ BitmapHeapNext(BitmapHeapScanState *node)
CHECK_FOR_INTERRUPTS();
-#ifdef USE_PREFETCH
-
- /*
- * Try to prefetch at least a few pages even before we get to the
- * second page if we don't stop reading after the first tuple.
- */
- if (!pstate)
- {
- if (node->prefetch_target < node->prefetch_maximum)
- node->prefetch_target++;
- }
- else if (pstate->prefetch_target < node->prefetch_maximum)
- {
- /* take spinlock while updating shared state */
- SpinLockAcquire(&pstate->mutex);
- if (pstate->prefetch_target < node->prefetch_maximum)
- pstate->prefetch_target++;
- SpinLockRelease(&pstate->mutex);
- }
-#endif /* USE_PREFETCH */
-
- /*
- * We issue prefetch requests *after* fetching the current page to
- * try to avoid having prefetching interfere with the main I/O.
- * Also, this should happen only when we have determined there is
- * still something to do on the current page, else we may
- * uselessly prefetch the same page we are just about to request
- * for real.
- */
- BitmapPrefetch(node, scan);
-
/*
* If we are using lossy info, we have to recheck the qual
* conditions at every tuple.
@@ -238,23 +207,9 @@ BitmapHeapNext(BitmapHeapScanState *node)
new_page:
- BitmapAdjustPrefetchIterator(node);
-
if (!table_scan_bitmap_next_block(scan, &node->blockno, &node->recheck,
&node->lossy_pages, &node->exact_pages))
break;
-
- /*
- * If serial, we can error out if the the prefetch block doesn't stay
- * ahead of the current block.
- */
- if (node->pstate == NULL &&
- !node->prefetch_iterator.exhausted &&
- node->pfblockno < node->blockno)
- elog(ERROR, "prefetch and main iterators are out of sync");
-
- /* Adjust the prefetch target */
- BitmapAdjustPrefetchTarget(node);
}
/*
@@ -319,22 +274,13 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
{
PlanState *outerPlan = outerPlanState(node);
- /* release bitmaps and buffers if any */
- if (node->prefetch_iterator.exhausted)
- unified_tbm_end_iterate(&node->prefetch_iterator);
+ /* release bitmaps if any */
if (node->tbm)
tbm_free(node->tbm);
- if (node->pvmbuffer != InvalidBuffer)
- ReleaseBuffer(node->pvmbuffer);
node->tbm = NULL;
node->initialized = false;
- node->pvmbuffer = InvalidBuffer;
node->recheck = true;
node->blockno = InvalidBlockNumber;
- node->pfblockno = InvalidBlockNumber;
- /* Only used for serial BHS */
- node->prefetch_pages = 0;
- node->prefetch_target = -1;
ExecScanReScan(&node->ss);
@@ -373,14 +319,10 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node)
table_endscan_bm(scanDesc);
/*
- * release bitmaps and buffers if any
+ * release bitmaps if any
*/
- if (!node->prefetch_iterator.exhausted)
- unified_tbm_end_iterate(&node->prefetch_iterator);
if (node->tbm)
tbm_free(node->tbm);
- if (node->pvmbuffer != InvalidBuffer)
- ReleaseBuffer(node->pvmbuffer);
}
/* ----------------------------------------------------------------
@@ -413,16 +355,12 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
scanstate->ss.ps.ExecProcNode = ExecBitmapHeapScan;
scanstate->tbm = NULL;
- scanstate->pvmbuffer = InvalidBuffer;
scanstate->exact_pages = 0;
scanstate->lossy_pages = 0;
- scanstate->prefetch_pages = 0;
- scanstate->prefetch_target = -1;
scanstate->initialized = false;
scanstate->pstate = NULL;
scanstate->recheck = true;
scanstate->blockno = InvalidBlockNumber;
- scanstate->pfblockno = InvalidBlockNumber;
/*
* Miscellaneous initialization
@@ -462,13 +400,6 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
scanstate->bitmapqualorig =
ExecInitQual(node->bitmapqualorig, (PlanState *) scanstate);
- /*
- * Maximum number of prefetches for the tablespace if configured,
- * otherwise the current value of the effective_io_concurrency GUC.
- */
- scanstate->prefetch_maximum =
- get_tablespace_io_concurrency(currentRelation->rd_rel->reltablespace);
-
scanstate->ss.ss_currentRelation = currentRelation;
/*
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index f0cd0041460..b17f0e8b4e6 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -92,6 +92,10 @@ typedef struct BitmapHeapScanDescData
* Members common to Parallel and Serial BitmapHeapScan
*/
UnifiedTBMIterator iterator;
+ UnifiedTBMIterator prefetch_iterator;
+
+ /* maximum value for prefetch_target */
+ int prefetch_maximum;
/*
* These fields are only used for bitmap scans for the "skip fetch"
@@ -101,7 +105,26 @@ typedef struct BitmapHeapScanDescData
* to return. They are common to parallel and serial BitmapHeapScans
*/
Buffer vmbuffer;
+ /* buffer for visibility-map lookups of prefetched pages */
+ Buffer pvmbuffer;
int empty_tuples_pending;
+
+ /*
+ * Parallel-only members
+ */
+
+ struct ParallelBitmapHeapState *pstate;
+
+ /*
+ * Serial-only members
+ */
+
+ /* Current target for prefetch distance */
+ int prefetch_target;
+ /* # pages prefetch iterator is ahead of current */
+ int prefetch_pages;
+ /* used to validate prefetch block stays ahead of current block */
+ BlockNumber pfblockno;
} BitmapHeapScanDescData;
typedef struct BitmapHeapScanDescData *BitmapHeapScanDesc;
@@ -305,7 +328,8 @@ extern bool heap_getnextslot_tidrange(TableScanDesc sscan,
extern TableScanDesc heap_beginscan_bm(Relation relation, Snapshot snapshot, uint32 flags);
extern void heap_endscan_bm(TableScanDesc scan);
extern void heap_rescan_bm(TableScanDesc sscan, TIDBitmap *tbm,
- ParallelBitmapHeapState *pstate, dsa_area *dsa);
+ ParallelBitmapHeapState *pstate, dsa_area *dsa,
+ int prefetch_maximum);
extern bool heap_fetch(Relation relation, Snapshot snapshot,
HeapTuple tuple, Buffer *userbuf, bool keep_buf);
extern bool heap_hot_search_buffer(ItemPointer tid, Relation relation,
@@ -422,9 +446,6 @@ extern bool heapam_scan_analyze_next_tuple(TableScanDesc scan,
TransactionId OldestXmin,
double *liverows, double *deadrows,
TupleTableSlot *slot);
-extern void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node);
-extern void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node);
-extern void BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan);
/*
* To avoid leaking too much knowledge about reorderbuffer implementation
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index aebcecad30d..06530536897 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -368,7 +368,8 @@ typedef struct TableAmRoutine
uint32 flags);
void (*scan_rescan_bm) (TableScanDesc scan, TIDBitmap *tbm,
- ParallelBitmapHeapState *pstate, dsa_area *dsa);
+ ParallelBitmapHeapState *pstate, dsa_area *dsa,
+ int prefetch_maximum);
/*
* Release resources and deallocate scan.
@@ -805,17 +806,6 @@ typedef struct TableAmRoutine
* lossy_pages is incremented if the bitmap is lossy for the selected
* block; otherwise, exact_pages is incremented.
*
- * XXX: Currently this may only be implemented if the AM uses md.c as its
- * storage manager, and uses ItemPointer->ip_blkid in a manner that maps
- * blockids directly to the underlying storage. nodeBitmapHeapscan.c
- * performs prefetching directly using that interface. This probably
- * needs to be rectified at a later point.
- *
- * XXX: Currently this may only be implemented if the AM uses the
- * visibilitymap, as nodeBitmapHeapscan.c unconditionally accesses it to
- * perform prefetching. This probably needs to be rectified at a later
- * point.
- *
* Optional callback, but either both scan_bitmap_next_block and
* scan_bitmap_next_tuple need to exist, or neither.
*/
@@ -954,7 +944,7 @@ table_beginscan_strat(Relation rel, Snapshot snapshot,
*/
static inline TableScanDesc
table_beginscan_bm(TableScanDesc scan, Relation rel, Snapshot snapshot,
- bool need_tuple, TIDBitmap *tbm,
+ bool need_tuple, int prefetch_maximum, TIDBitmap *tbm,
ParallelBitmapHeapState *pstate, dsa_area *dsa)
{
uint32 flags = SO_TYPE_BITMAPSCAN | SO_ALLOW_PAGEMODE;
@@ -969,7 +959,7 @@ table_beginscan_bm(TableScanDesc scan, Relation rel, Snapshot snapshot,
if (!scan)
scan = rel->rd_tableam->scan_begin_bm(rel, snapshot, flags);
- scan->rs_rd->rd_tableam->scan_rescan_bm(scan, tbm, pstate, dsa);
+ scan->rs_rd->rd_tableam->scan_rescan_bm(scan, tbm, pstate, dsa, prefetch_maximum);
return scan;
}
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 6693cf66c77..713de7d50f6 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1792,18 +1792,12 @@ typedef struct ParallelBitmapHeapState
*
* bitmapqualorig execution state for bitmapqualorig expressions
* tbm bitmap obtained from child index scan(s)
- * pvmbuffer buffer for visibility-map lookups of prefetched pages
* exact_pages total number of exact pages retrieved
* lossy_pages total number of lossy pages retrieved
- * prefetch_iterator for prefetching ahead of current page
- * prefetch_pages # pages prefetch iterator is ahead of current
- * prefetch_target current target prefetch distance
- * prefetch_maximum maximum value for prefetch_target
* initialized is node is ready to iterate
* pstate shared state for parallel bitmap scan
* recheck do current page's tuples need recheck
* blockno used to validate pf and current block in sync
- * pfblockno used to validate pf stays ahead of current block
* ----------------
*/
typedef struct BitmapHeapScanState
@@ -1811,18 +1805,12 @@ typedef struct BitmapHeapScanState
ScanState ss; /* its first field is NodeTag */
ExprState *bitmapqualorig;
TIDBitmap *tbm;
- Buffer pvmbuffer;
long exact_pages;
long lossy_pages;
- int prefetch_pages;
- int prefetch_target;
- int prefetch_maximum;
bool initialized;
- UnifiedTBMIterator prefetch_iterator;
ParallelBitmapHeapState *pstate;
bool recheck;
BlockNumber blockno;
- BlockNumber pfblockno;
} BitmapHeapScanState;
/* ----------------
--
2.40.1
--clv5reqgj4vdihqz
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v19-0020-Move-BitmapHeapScan-initialization-to-helper.patch"
view thread (10+ messages)
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH v19 19/21] Push BitmapHeapScan prefetch code into heap AM
In-Reply-To: <no-message-id-73707@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox