From 185c9469feff2deca7801882a3747008aab22966 Mon Sep 17 00:00:00 2001 From: Andrey Borodin Date: Sat, 19 Oct 2024 12:46:29 +0500 Subject: [PATCH v4 1/4] Prototype B-tree vacuum streamlineing Signed-off-by: Andrey Borodin Signed-off-by: Junwang Zhao --- src/backend/access/nbtree/nbtree.c | 46 ++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index f4f79f2..2dc89cb 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -88,7 +88,7 @@ typedef struct BTParallelScanDescData *BTParallelScanDesc; static void btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state, BTCycleId cycleid); -static void btvacuumpage(BTVacState *vstate, BlockNumber scanblkno); +static void btvacuumpage(BTVacState *vstate, Buffer buf); static BTVacuumPosting btreevacuumposting(BTVacState *vstate, IndexTuple posting, OffsetNumber updatedoffset, @@ -971,6 +971,8 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, BlockNumber num_pages; BlockNumber scanblkno; bool needLock; + BlockRangeReadStreamPrivate p; + ReadStream *stream = NULL; /* * Reset fields that track information about the entire index now. This @@ -1040,6 +1042,13 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, needLock = !RELATION_IS_LOCAL(rel); scanblkno = BTREE_METAPAGE + 1; + stream = read_stream_begin_relation(READ_STREAM_FULL, + info->strategy, + rel, + MAIN_FORKNUM, + block_range_read_stream_cb, + &p, + 0); for (;;) { /* Get the current relation length */ @@ -1056,15 +1065,27 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, /* Quit if we've scanned the whole relation */ if (scanblkno >= num_pages) break; + + p.current_blocknum = scanblkno; + p.last_exclusive = num_pages; + /* + * After reaching the end we have to reset stream to use it again. + * Extra restart in case of just one iteration does not cost us much. + */ + read_stream_reset(stream); + /* Iterate over pages, then loop back to recheck length */ for (; scanblkno < num_pages; scanblkno++) { - btvacuumpage(&vstate, scanblkno); + Buffer buf = read_stream_next_buffer(stream, NULL); + btvacuumpage(&vstate, buf); if (info->report_progress) pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_DONE, scanblkno); } + Assert(read_stream_next_buffer(stream, NULL) == InvalidBuffer); } + read_stream_end(stream); /* Set statistics num_pages field to final size of index */ stats->num_pages = num_pages; @@ -1096,7 +1117,7 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, * recycled (i.e. before the page split). */ static void -btvacuumpage(BTVacState *vstate, BlockNumber scanblkno) +btvacuumpage(BTVacState *vstate, Buffer buf) { IndexVacuumInfo *info = vstate->info; IndexBulkDeleteResult *stats = vstate->stats; @@ -1107,7 +1128,7 @@ btvacuumpage(BTVacState *vstate, BlockNumber scanblkno) bool attempt_pagedel; BlockNumber blkno, backtrack_to; - Buffer buf; + BlockNumber scanblkno = BufferGetBlockNumber(buf); Page page; BTPageOpaque opaque; @@ -1121,14 +1142,6 @@ backtrack: /* call vacuum_delay_point while not holding any buffer lock */ vacuum_delay_point(); - /* - * We can't use _bt_getbuf() here because it always applies - * _bt_checkpage(), which will barf on an all-zero page. We want to - * recycle all-zero pages, not fail. Also, we want to use a nondefault - * buffer access strategy. - */ - buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, - info->strategy); _bt_lockbuf(rel, buf, BT_READ); page = BufferGetPage(buf); opaque = NULL; @@ -1415,6 +1428,15 @@ backtrack: if (backtrack_to != P_NONE) { blkno = backtrack_to; + + /* + * We can't use _bt_getbuf() here because it always applies + * _bt_checkpage(), which will barf on an all-zero page. We want to + * recycle all-zero pages, not fail. Also, we want to use a nondefault + * buffer access strategy. + */ + buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, + info->strategy); goto backtrack; } } -- 2.39.5 (Apple Git-154)