From 8a240e541c06ea8245e3d4d917321be62a63fe71 Mon Sep 17 00:00:00 2001 From: Andrey Borodin Date: Fri, 18 Sep 2020 20:28:16 +0500 Subject: [PATCH v3] Use new log_newpages() routine in B-tree build --- src/backend/access/nbtree/nbtsort.c | 51 ++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index efee86784b..7abd50faca 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -254,6 +254,14 @@ typedef struct BTWriteState BlockNumber btws_pages_alloced; /* # pages allocated */ BlockNumber btws_pages_written; /* # pages written out */ Page btws_zeropage; /* workspace for filling zeroes */ + + + BlockNumber pages_allocated; + BlockNumber pages_written; + + int ready_num_pages; + BlockNumber ready_blknos[XLR_MAX_BLOCK_ID]; + Page ready_pages[XLR_MAX_BLOCK_ID]; } BTWriteState; @@ -290,7 +298,36 @@ static void _bt_parallel_scan_and_sort(BTSpool *btspool, BTSpool *btspool2, BTShared *btshared, Sharedsort *sharedsort, Sharedsort *sharedsort2, int sortmem, bool progress); +static void _bt_indexsortbuild_flush_ready_pages(BTWriteState *state); + +/* + * A bogus LSN value used during index build. Must be smaller than any + * real or fake unlogged LSN, so that after an index build finishes, all the + * splits are considered completed. + */ +#define NBTreeBuildLSN ((XLogRecPtr) 1) + +static void +_bt_indexsortbuild_flush_ready_pages(BTWriteState *state) +{ + if (state->ready_num_pages == 0) + return; + + for (int i = 0; i < state->ready_num_pages; i++) + { + Page page = state->ready_pages[i]; + PageSetLSN(page, NBTreeBuildLSN); + } + + log_newpages(&state->index->rd_node, MAIN_FORKNUM, state->ready_num_pages, + state->ready_blknos, state->ready_pages, true); + + for (int i = 0; i < state->ready_num_pages; i++) + pfree(state->ready_pages[i]); + + state->ready_num_pages = 0; +} /* * btbuild() -- build a new btree index. @@ -569,6 +606,9 @@ _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2) wstate.btws_pages_alloced = BTREE_METAPAGE + 1; wstate.btws_pages_written = 0; wstate.btws_zeropage = NULL; /* until needed */ + wstate.ready_num_pages = 0; + wstate.pages_allocated = 0; + wstate.pages_written = 0; pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE, PROGRESS_BTREE_PHASE_LEAF_LOAD); @@ -643,8 +683,12 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno) /* XLOG stuff */ if (wstate->btws_use_wal) { - /* We use the XLOG_FPI record type for this */ - log_newpage(&wstate->index->rd_node, MAIN_FORKNUM, blkno, page, true); + if (wstate->ready_num_pages == XLR_MAX_BLOCK_ID) + _bt_indexsortbuild_flush_ready_pages(wstate); + + wstate->ready_blknos[wstate->ready_num_pages] = blkno; + wstate->ready_pages[wstate->ready_num_pages] = page; + wstate->ready_num_pages++; } /* @@ -684,8 +728,6 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno) smgrwrite(wstate->index->rd_smgr, MAIN_FORKNUM, blkno, (char *) page, true); } - - pfree(page); } /* @@ -1171,6 +1213,7 @@ _bt_uppershutdown(BTWriteState *wstate, BTPageState *state) _bt_initmetapage(metapage, rootblkno, rootlevel, wstate->inskey->allequalimage); _bt_blwritepage(wstate, metapage, BTREE_METAPAGE); + _bt_indexsortbuild_flush_ready_pages(wstate); } /* -- 2.24.3 (Apple Git-128)