agora inbox for [email protected]
help / color / mirror / Atom feedFrom: Melanie Plageman <[email protected]>
Subject: [PATCH v16 16/18] Push BitmapHeapScan prefetch code into heap AM
Date: Fri, 5 Apr 2024 18:48:27 -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 | 33 +++++-
src/backend/access/heap/heapam_handler.c | 125 +++++++++++++++-------
src/backend/executor/nodeBitmapHeapscan.c | 98 +++--------------
src/include/access/heapam.h | 29 ++++-
src/include/access/tableam.h | 18 +---
src/include/executor/nodeBitmapHeapscan.h | 7 ++
src/include/nodes/execnodes.h | 19 ----
7 files changed, 168 insertions(+), 161 deletions(-)
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index c35dc3c4e7..5728b2ea8a 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -975,8 +975,10 @@ heap_beginscan_bm(Relation relation, Snapshot snapshot, uint32 flags)
scan->iterator.serial = NULL;
scan->iterator.parallel = NULL;
-
scan->vmbuffer = InvalidBuffer;
+ scan->pf_iterator.serial = NULL;
+ scan->pf_iterator.parallel = NULL;
+ scan->pvmbuffer = InvalidBuffer;
return (TableScanDesc) scan;
}
@@ -1081,6 +1083,10 @@ heap_endscan_bm(TableScanDesc sscan)
if (BufferIsValid(scan->vmbuffer))
ReleaseBuffer(scan->vmbuffer);
+ if (BufferIsValid(scan->pvmbuffer))
+ ReleaseBuffer(scan->pvmbuffer);
+
+ bhs_end_iterate(&scan->pf_iterator);
bhs_end_iterate(&scan->iterator);
/*
@@ -1390,7 +1396,7 @@ heap_getnextslot_tidrange(TableScanDesc sscan, ScanDirection direction,
void
heap_rescan_bm(TableScanDesc sscan, TIDBitmap *tbm,
- ParallelBitmapHeapState *pstate, dsa_area *dsa)
+ ParallelBitmapHeapState *pstate, dsa_area *dsa, int pf_maximum)
{
BitmapHeapScanDesc scan = (BitmapHeapScanDesc) sscan;
@@ -1401,9 +1407,19 @@ heap_rescan_bm(TableScanDesc sscan, TIDBitmap *tbm,
ReleaseBuffer(scan->vmbuffer);
scan->vmbuffer = InvalidBuffer;
+ if (BufferIsValid(scan->pvmbuffer))
+ ReleaseBuffer(scan->pvmbuffer);
+ scan->pvmbuffer = InvalidBuffer;
+
+ bhs_end_iterate(&scan->pf_iterator);
bhs_end_iterate(&scan->iterator);
+ scan->prefetch_maximum = 0;
scan->empty_tuples_pending = 0;
+ scan->pstate = NULL;
+ scan->prefetch_target = -1;
+ scan->prefetch_pages = 0;
+ scan->pfblockno = InvalidBlockNumber;
/*
* reinitialize heap scan descriptor
@@ -1414,6 +1430,19 @@ heap_rescan_bm(TableScanDesc sscan, TIDBitmap *tbm,
pstate ?
pstate->tbmiterator :
InvalidDsaPointer);
+
+#ifdef USE_PREFETCH
+ if (pf_maximum > 0)
+ {
+ bhs_begin_iterate(&scan->pf_iterator, tbm, dsa,
+ pstate ?
+ pstate->prefetch_iterator :
+ InvalidDsaPointer);
+ }
+#endif /* USE_PREFETCH */
+
+ scan->pstate = pstate;
+ scan->prefetch_maximum = pf_maximum;
}
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index ebaba33406..fca9c7233e 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;
- BitmapHeapIterator *prefetch_iterator = &node->pf_iterator;
+ BitmapHeapIterator *prefetch_iterator = &scan->pf_iterator;
+ ParallelBitmapHeapState *pstate = scan->pstate;
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 = bhs_iterate(prefetch_iterator);
- node->pfblockno = tbmpre ? tbmpre->blockno : InvalidBlockNumber;
+ scan->pfblockno = tbmpre ? tbmpre->blockno : InvalidBlockNumber;
}
return;
}
@@ -2216,7 +2219,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node)
* table_scan_bitmap_next_block() keeps prefetch distance higher across
* the parallel workers.
*/
- if (node->prefetch_maximum > 0)
+ if (scan->prefetch_maximum > 0)
{
SpinLockAcquire(&pstate->mutex);
if (pstate->prefetch_pages > 0)
@@ -2240,7 +2243,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node)
if (!prefetch_iterator->exhausted)
{
tbmpre = bhs_iterate(prefetch_iterator);
- node->pfblockno = tbmpre ? tbmpre->blockno : InvalidBlockNumber;
+ scan->pfblockno = tbmpre ? tbmpre->blockno : InvalidBlockNumber;
}
}
}
@@ -2256,33 +2259,34 @@ 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;
+ int prefetch_maximum = scan->prefetch_maximum;
if (pstate == NULL)
{
- if (node->prefetch_target >= node->prefetch_maximum)
+ if (scan->prefetch_target >= 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 >= prefetch_maximum / 2)
+ scan->prefetch_target = 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 < prefetch_maximum)
{
SpinLockAcquire(&pstate->mutex);
- if (pstate->prefetch_target >= node->prefetch_maximum)
+ if (pstate->prefetch_target >= 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 >= prefetch_maximum / 2)
+ pstate->prefetch_target = prefetch_maximum;
else if (pstate->prefetch_target > 0)
pstate->prefetch_target *= 2;
else
@@ -2295,18 +2299,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;
- BitmapHeapIterator *prefetch_iterator = &node->pf_iterator;
+ ParallelBitmapHeapState *pstate = scan->pstate;
+ BitmapHeapIterator *prefetch_iterator = &scan->pf_iterator;
+ Relation rel = scan->heap_common.rs_base.rs_rd;
if (pstate == NULL)
{
if (!prefetch_iterator->exhausted)
{
- while (node->prefetch_pages < node->prefetch_target)
+ while (scan->prefetch_pages < scan->prefetch_target)
{
TBMIterateResult *tbmpre = bhs_iterate(prefetch_iterator);
bool skip_fetch;
@@ -2317,8 +2322,8 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
bhs_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,
@@ -2326,14 +2331,14 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
* logic normally. (Would it be better not to increment
* prefetch_pages?)
*/
- skip_fetch = (!(scan->rs_flags & SO_NEED_TUPLE) &&
+ skip_fetch = (!(scan->heap_common.rs_base.rs_flags & SO_NEED_TUPLE) &&
!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);
}
}
@@ -2373,17 +2378,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_TUPLE) &&
+ skip_fetch = (!(scan->heap_common.rs_base.rs_flags & SO_NEED_TUPLE) &&
!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);
}
}
}
@@ -2416,6 +2421,8 @@ heapam_scan_bitmap_next_block(TableScanDesc sscan,
*blockno = InvalidBlockNumber;
*recheck = true;
+ BitmapAdjustPrefetchIterator(scan);
+
do
{
CHECK_FOR_INTERRUPTS();
@@ -2556,6 +2563,18 @@ 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->pf_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,
@@ -2592,6 +2611,36 @@ heapam_scan_bitmap_next_tuple(TableScanDesc scan,
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 (!bscan->pstate)
+ {
+ if (bscan->prefetch_target < bscan->prefetch_maximum)
+ bscan->prefetch_target++;
+ }
+ else if (bscan->pstate->prefetch_target < bscan->prefetch_maximum)
+ {
+ /* take spinlock while updating shared state */
+ SpinLockAcquire(&bscan->pstate->mutex);
+ if (bscan->pstate->prefetch_target < bscan->prefetch_maximum)
+ bscan->pstate->prefetch_target++;
+ SpinLockRelease(&bscan->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(bscan);
+#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 6f1afd427d..ae36dfd773 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -124,7 +124,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
@@ -148,7 +147,9 @@ BitmapHeapNext(BitmapHeapScanState *node)
*/
if (!node->initialized)
{
+ Relation rel = node->ss.ss_currentRelation;
uint32 extra_flags = 0;
+ bool pf_maximum = 0;
/*
* The leader will immediately come out of the function, but others
@@ -157,6 +158,15 @@ 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
+ pf_maximum = get_tablespace_io_concurrency(rel->rd_rel->reltablespace);
+#endif
+
+
if (!pstate || init_shared_state)
{
tbm = (TIDBitmap *) MultiExecProcNode(outerPlanState(node));
@@ -174,7 +184,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
*/
pstate->tbmiterator = tbm_prepare_shared_iterate(tbm);
#ifdef USE_PREFETCH
- if (node->prefetch_maximum > 0)
+ if (pf_maximum > 0)
{
pstate->prefetch_iterator =
tbm_prepare_shared_iterate(tbm);
@@ -200,25 +210,16 @@ BitmapHeapNext(BitmapHeapScanState *node)
* scan descriptor and begin the scan.
*/
scan = table_beginscan_bm(node->ss.ss_currentScanDesc,
- node->ss.ss_currentRelation,
+ rel,
node->ss.ps.state->es_snapshot,
extra_flags,
+ pf_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)
- {
- bhs_begin_iterate(&node->pf_iterator, tbm, dsa,
- pstate ?
- pstate->prefetch_iterator :
- InvalidDsaPointer);
- }
-#endif /* USE_PREFETCH */
-
node->initialized = true;
goto new_page;
@@ -230,37 +231,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.
@@ -283,23 +253,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->pf_iterator.exhausted &&
- node->pfblockno < node->blockno)
- elog(ERROR, "prefetch and main iterators are out of sync");
-
- /* Adjust the prefetch target */
- BitmapAdjustPrefetchTarget(node);
}
/*
@@ -365,21 +321,12 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
PlanState *outerPlan = outerPlanState(node);
/* release bitmaps and buffers if any */
- if (node->pf_iterator.exhausted)
- bhs_end_iterate(&node->pf_iterator);
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);
@@ -418,14 +365,10 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node)
table_endscan_bm(scanDesc);
/*
- * release bitmaps and buffers if any
+ * release bitmaps if any
*/
- if (!node->pf_iterator.exhausted)
- bhs_end_iterate(&node->pf_iterator);
if (node->tbm)
tbm_free(node->tbm);
- if (node->pvmbuffer != InvalidBuffer)
- ReleaseBuffer(node->pvmbuffer);
}
/* ----------------------------------------------------------------
@@ -458,16 +401,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
@@ -507,13 +446,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 f81a295685..499e739da7 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -93,6 +93,10 @@ typedef struct BitmapHeapScanDescData
* Members common to Parallel and Serial BitmapHeapScan
*/
BitmapHeapIterator iterator;
+ BitmapHeapIterator pf_iterator;
+
+ /* maximum value for prefetch_target */
+ int prefetch_maximum;
/*
* These fields are only used for bitmap scans for the "skip fetch"
@@ -102,7 +106,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;
@@ -307,7 +330,7 @@ extern TableScanDesc heap_beginscan_bm(Relation relation, Snapshot snapshot, uin
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 pf_maximum);
extern bool heap_fetch(Relation relation, Snapshot snapshot,
HeapTuple tuple, Buffer *userbuf, bool keep_buf);
@@ -426,10 +449,6 @@ extern bool heapam_scan_analyze_next_tuple(TableScanDesc scan,
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
* details this is implemented in reorderbuffer.c not heapam_visibility.c
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index f344d97f1f..9ec0a1da2b 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -399,7 +399,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 pf_maximum);
/*
* Release resources and deallocate scan. If TableScanDesc.temp_snap,
@@ -801,17 +802,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.
*/
@@ -950,7 +940,7 @@ table_beginscan_strat(Relation rel, Snapshot snapshot,
*/
static inline TableScanDesc
table_beginscan_bm(TableScanDesc scan, Relation rel, Snapshot snapshot,
- uint32 extra_flags, TIDBitmap *tbm,
+ uint32 extra_flags, int pf_maximum, TIDBitmap *tbm,
ParallelBitmapHeapState *pstate, dsa_area *dsa)
{
uint32 flags = SO_TYPE_BITMAPSCAN | SO_ALLOW_PAGEMODE | extra_flags;
@@ -962,7 +952,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, pf_maximum);
return scan;
}
diff --git a/src/include/executor/nodeBitmapHeapscan.h b/src/include/executor/nodeBitmapHeapscan.h
index 7064f54686..028081db32 100644
--- a/src/include/executor/nodeBitmapHeapscan.h
+++ b/src/include/executor/nodeBitmapHeapscan.h
@@ -29,6 +29,13 @@ extern void ExecBitmapHeapReInitializeDSM(BitmapHeapScanState *node,
extern void ExecBitmapHeapInitializeWorker(BitmapHeapScanState *node,
ParallelWorkerContext *pwcxt);
+typedef struct BitmapHeapIterator
+{
+ struct TBMIterator *serial;
+ struct TBMSharedIterator *parallel;
+ bool exhausted;
+} BitmapHeapIterator;
+
extern TBMIterateResult *bhs_iterate(BitmapHeapIterator *iterator);
extern void bhs_begin_iterate(BitmapHeapIterator *iterator, TIDBitmap *tbm,
dsa_area *dsa, dsa_pointer dsp);
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 714eb3e534..713de7d50f 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1787,30 +1787,17 @@ typedef struct ParallelBitmapHeapState
ConditionVariable cv;
} ParallelBitmapHeapState;
-typedef struct BitmapHeapIterator
-{
- struct TBMIterator *serial;
- struct TBMSharedIterator *parallel;
- bool exhausted;
-} BitmapHeapIterator;
-
/* ----------------
* BitmapHeapScanState information
*
* 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
- * pf_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
@@ -1818,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;
- BitmapHeapIterator pf_iterator;
ParallelBitmapHeapState *pstate;
bool recheck;
BlockNumber blockno;
- BlockNumber pfblockno;
} BitmapHeapScanState;
/* ----------------
--
2.40.1
--e3xl7h75mzefinno
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v16-0017-Move-BitmapHeapScan-initialization-to-helper.patch"
view thread (10+ messages) latest in thread
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 v16 16/18] Push BitmapHeapScan prefetch code into heap AM
In-Reply-To: <no-message-id-73605@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