From: Melanie Plageman Date: Fri, 5 Apr 2024 18:48:27 -0400 Subject: [PATCH v16 16/18] Push BitmapHeapScan prefetch code into heap AM 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"