From 27707c89a7946018169adc840db4f5aa34e03d10 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Tue, 21 Apr 2020 09:40:34 -0700 Subject: [PATCH v1] Fix nbtdedup.c single value strategy issue. --- src/include/access/nbtree.h | 1 + src/backend/access/nbtree/nbtdedup.c | 20 +++++++++++++++----- src/backend/access/nbtree/nbtsort.c | 1 + src/backend/access/nbtree/nbtxlog.c | 1 + 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index 3b2bcb22a7..79506c748b 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -739,6 +739,7 @@ typedef struct BTDedupStateData { /* Deduplication status info for entire pass over page */ bool deduplicate; /* Still deduplicating page? */ + int nmaxitems; /* Number of max-sized tuples so far */ Size maxpostingsize; /* Limit on size of final tuple */ /* Metadata about base tuple of current pending posting list */ diff --git a/src/backend/access/nbtree/nbtdedup.c b/src/backend/access/nbtree/nbtdedup.c index b20faf693d..f1a884a220 100644 --- a/src/backend/access/nbtree/nbtdedup.c +++ b/src/backend/access/nbtree/nbtdedup.c @@ -62,7 +62,6 @@ _bt_dedup_one_page(Relation rel, Buffer buf, Relation heapRel, Page page = BufferGetPage(buf); BTPageOpaque opaque; Page newpage; - int newpagendataitems = 0; OffsetNumber deletable[MaxIndexTuplesPerPage]; BTDedupState state; int ndeletable = 0; @@ -124,6 +123,7 @@ _bt_dedup_one_page(Relation rel, Buffer buf, Relation heapRel, */ state = (BTDedupState) palloc(sizeof(BTDedupStateData)); state->deduplicate = true; + state->nmaxitems = 0; state->maxpostingsize = Min(BTMaxItemSize(page) / 2, INDEX_SIZE_MASK); /* Metadata about base tuple of current pending posting list */ state->base = NULL; @@ -204,7 +204,6 @@ _bt_dedup_one_page(Relation rel, Buffer buf, Relation heapRel, * reset the state and move on without modifying the page. */ pagesaving += _bt_dedup_finish_pending(newpage, state); - newpagendataitems++; if (singlevalstrat) { @@ -221,9 +220,9 @@ _bt_dedup_one_page(Relation rel, Buffer buf, Relation heapRel, * current call generated the maxpostingsize-capped duplicate * tuples at the start of the page. */ - if (newpagendataitems == 5) + if (state->nmaxitems == 5) _bt_singleval_fillfactor(page, state, newitemsz); - else if (newpagendataitems == 6) + else if (state->nmaxitems == 6) { state->deduplicate = false; singlevalstrat = false; /* won't be back here */ @@ -237,7 +236,6 @@ _bt_dedup_one_page(Relation rel, Buffer buf, Relation heapRel, /* Handle the last item */ pagesaving += _bt_dedup_finish_pending(newpage, state); - newpagendataitems++; /* * If no items suitable for deduplication were found, newpage must be @@ -404,7 +402,19 @@ _bt_dedup_save_htid(BTDedupState state, IndexTuple itup) (state->nhtids + nhtids) * sizeof(ItemPointerData)); if (mergedtupsz > state->maxpostingsize) + { + /* + * Count this as an oversized item for single value strategy, though + * only when there will be 20 TIDs in final posting list tuple. This + * limit (which is arbitrary) avoids confusion about how many 1/6 of a + * page tuples have really been encountered/created by the current + * deduplication pass. + */ + if (state->nhtids > 20) + state->nmaxitems++; + return false; + } /* * Save heap TIDs to pending posting list tuple -- itup can be merged into diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index 15f10a29d3..719887b133 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -1310,6 +1310,7 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2) dstate = (BTDedupState) palloc(sizeof(BTDedupStateData)); dstate->deduplicate = true; /* unused */ + dstate->nmaxitems = 0; /* unused */ dstate->maxpostingsize = 0; /* set later */ /* Metadata about base tuple of current pending posting list */ dstate->base = NULL; diff --git a/src/backend/access/nbtree/nbtxlog.c b/src/backend/access/nbtree/nbtxlog.c index 87a8612c28..5bec59d448 100644 --- a/src/backend/access/nbtree/nbtxlog.c +++ b/src/backend/access/nbtree/nbtxlog.c @@ -483,6 +483,7 @@ btree_xlog_dedup(XLogReaderState *record) state = (BTDedupState) palloc(sizeof(BTDedupStateData)); state->deduplicate = true; /* unused */ + state->nmaxitems = 0; /* unused */ /* Conservatively use larger maxpostingsize than primary */ state->maxpostingsize = BTMaxItemSize(page); state->base = NULL; -- 2.25.1