From 6dfae936a29e2d3479273f8ab47778a596258b16 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Wed, 6 Mar 2024 21:03:19 +0200 Subject: [PATCH v6 8/9] Track 'current_block' in the skip state The caller was expected to always pass last blk + 1. It's not clear if the next_unskippable block accounting would work correctly if you passed something else. So rather than expecting the caller to do that, have heap_vac_scan_get_next_block() keep track of the last returned block itself, in the 'skip' state. This is largely redundant with the LVRelState->blkno field. But that one is currently only used for error reporting, so it feels best to give heap_vac_scan_get_next_block() its own field that it owns. --- src/backend/access/heap/vacuumlazy.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 17e06065f7e..535d70b71c3 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -211,6 +211,8 @@ typedef struct LVRelState */ struct { + BlockNumber current_block; + /* Next unskippable block */ BlockNumber next_unskippable_block; /* Next unskippable block's visibility status */ @@ -228,7 +230,7 @@ typedef struct LVSavedErrInfo /* non-export function prototypes */ static void lazy_scan_heap(LVRelState *vacrel); -static bool heap_vac_scan_get_next_block(LVRelState *vacrel, BlockNumber next_block, +static bool heap_vac_scan_get_next_block(LVRelState *vacrel, BlockNumber *blkno, bool *all_visible_according_to_vm, Buffer *vmbuffer); @@ -831,10 +833,11 @@ lazy_scan_heap(LVRelState *vacrel) initprog_val[2] = dead_items->max_items; pgstat_progress_update_multi_param(3, initprog_index, initprog_val); + /* initialize for first heap_vac_scan_get_next_block() call */ + vacrel->get_next_block_state.current_block = InvalidBlockNumber; vacrel->get_next_block_state.next_unskippable_block = InvalidBlockNumber; - while (heap_vac_scan_get_next_block(vacrel, blkno + 1, - &blkno, &all_visible_according_to_vm, &vmbuffer)) + while (heap_vac_scan_get_next_block(vacrel, &blkno, &all_visible_according_to_vm, &vmbuffer)) { Buffer buf; Page page; @@ -1061,11 +1064,9 @@ lazy_scan_heap(LVRelState *vacrel) * heap_vac_scan_get_next_block() -- get next block for vacuum to process * * lazy_scan_heap() calls here every time it needs to get the next block to - * prune and vacuum, using the visibility map, vacuum options, and various - * thresholds to skip blocks which do not need to be processed. Caller passes - * next_block, the next block in line. This block may end up being skipped. - * heap_vac_scan_get_next_block() sets blkno to next block that actually needs - * to be processed. + * prune and vacuum. We use the visibility map, vacuum options, and various + * thresholds to skip blocks which do not need to be processed, and set blkno + * to next block that actually needs to be processed. * * A block is unskippable if it is not all visible according to the visibility * map. It is also unskippable if it is the last block in the relation, if the @@ -1104,14 +1105,16 @@ lazy_scan_heap(LVRelState *vacrel) * choice to skip such a range is actually made, making everything safe.) */ static bool -heap_vac_scan_get_next_block(LVRelState *vacrel, BlockNumber next_block, - BlockNumber *blkno, bool *all_visible_according_to_vm, Buffer *vmbuffer) +heap_vac_scan_get_next_block(LVRelState *vacrel, BlockNumber *blkno, + bool *all_visible_according_to_vm, Buffer *vmbuffer) { + /* Relies on InvalidBlockNumber + 1 == 0 */ + BlockNumber next_block = vacrel->get_next_block_state.current_block + 1; bool skipsallvis = false; if (next_block >= vacrel->rel_pages) { - *blkno = InvalidBlockNumber; + vacrel->get_next_block_state.current_block = *blkno = InvalidBlockNumber; return false; } @@ -1206,7 +1209,7 @@ heap_vac_scan_get_next_block(LVRelState *vacrel, BlockNumber next_block, else *all_visible_according_to_vm = true; - *blkno = next_block; + vacrel->get_next_block_state.current_block = *blkno = next_block; return true; } -- 2.39.2