From: Kyotaro Horiguchi Date: Tue, 26 Mar 2019 14:48:26 +0900 Subject: [PATCH 8/8] Optimize WAL-logging on btree bulk insertion Likewise the heap case, bulk insertion into btree can be optimized to omit WAL-logging on certain conditions. --- src/backend/access/heap/heapam.c | 13 +++++++++++++ src/backend/access/nbtree/nbtinsert.c | 5 ++++- src/backend/access/nbtree/nbtsort.c | 23 +++++++---------------- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 00416c4a99..c28b479141 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8870,6 +8870,8 @@ heap_mask(char *pagedata, BlockNumber blkno) void heap_register_sync(Relation rel) { + ListCell *indlist; + /* non-WAL-logged tables never need fsync */ if (!RelationNeedsWAL(rel)) return; @@ -8883,4 +8885,15 @@ heap_register_sync(Relation rel) RecordWALSkipping(toastrel); heap_close(toastrel, AccessShareLock); } + + /* Do the same to all index relations */ + foreach(indlist, RelationGetIndexList(rel)) + { + Oid indexId = lfirst_oid(indlist); + Relation indexRel; + + indexRel = index_open(indexId, AccessShareLock); + RecordWALSkipping(indexRel); + index_close(indexRel, NoLock); + } } diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index 96b7593fc1..fadcc09cb1 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -20,6 +20,7 @@ #include "access/tableam.h" #include "access/transam.h" #include "access/xloginsert.h" +#include "catalog/storage.h" #include "miscadmin.h" #include "storage/lmgr.h" #include "storage/predicate.h" @@ -1096,7 +1097,9 @@ _bt_insertonpg(Relation rel, cachedBlock = BufferGetBlockNumber(buf); /* XLOG stuff */ - if (RelationNeedsWAL(rel)) + if (BufferNeedsWAL(rel, buf) || + (!P_ISLEAF(lpageop) && BufferNeedsWAL(rel, cbuf)) || + (BufferIsValid(metabuf) && BufferNeedsWAL(rel, metabuf))) { xl_btree_insert xlrec; xl_btree_metadata xlmeta; diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index e65d4aab0f..90a5d6ae13 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -66,6 +66,7 @@ #include "access/xlog.h" #include "access/xloginsert.h" #include "catalog/index.h" +#include "catalog/storage.h" #include "miscadmin.h" #include "pgstat.h" #include "storage/smgr.h" @@ -264,7 +265,6 @@ typedef struct BTWriteState Relation heap; Relation index; BTScanInsert inskey; /* generic insertion scankey */ - bool btws_use_wal; /* dump pages to WAL? */ BlockNumber btws_pages_alloced; /* # pages allocated */ BlockNumber btws_pages_written; /* # pages written out */ Page btws_zeropage; /* workspace for filling zeroes */ @@ -334,6 +334,10 @@ btbuild(Relation heap, Relation index, IndexInfo *indexInfo) reltuples = _bt_spools_heapscan(heap, index, &buildstate, indexInfo); + /* Skip WAL-logging if wal_level = minimal */ + if (!XLogIsNeeded()) + RecordWALSkipping(index); + /* * Finish the build by (1) completing the sort of the spool file, (2) * inserting the sorted tuples into btree pages and (3) building the upper @@ -543,12 +547,6 @@ _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2) wstate.index = btspool->index; wstate.inskey = _bt_mkscankey(wstate.index, NULL); - /* - * We need to log index creation in WAL iff WAL archiving/streaming is - * enabled UNLESS the index isn't WAL-logged anyway. - */ - wstate.btws_use_wal = XLogIsNeeded() && RelationNeedsWAL(wstate.index); - /* reserve the metapage */ wstate.btws_pages_alloced = BTREE_METAPAGE + 1; wstate.btws_pages_written = 0; @@ -622,15 +620,8 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno) /* Ensure rd_smgr is open (could have been closed by relcache flush!) */ RelationOpenSmgr(wstate->index); - /* XLOG stuff - * - * Even if minimal mode, WAL is required here if truncation happened after - * being created in the same transaction. It is not needed otherwise but - * we don't bother identifying the case precisely. - */ - if (wstate->btws_use_wal || - (RelationNeedsWAL(wstate->index) && - (blkno == BTREE_METAPAGE && BTPageGetMeta(page)->btm_root == 0))) + /* XLOG stuff */ + if (BlockNeedsWAL(wstate->index, blkno)) { /* We use the heap NEWPAGE record type for this */ log_newpage(&wstate->index->rd_node, MAIN_FORKNUM, blkno, page, true); -- 2.16.3 ----Next_Part(Tue_Mar_26_16_35_07_2019_128)----