From: Melanie Plageman Date: Sat, 6 Apr 2024 16:21:04 -0400 Subject: [PATCH v19 19/21] 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 | 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"