From 2847e83ef91bfa3e3ebda6a8acd60bd835950716 Mon Sep 17 00:00:00 2001 From: Pavel Borisov Date: Thu, 25 Apr 2024 13:08:39 +0400 Subject: [PATCH v1 1/5] Amcheck: optimize speed of checking unique constraint Check heap visibility only for non-equal non-deduplicated index tuples. For deduplicated tuples we still need to check visibility of all posting list entries because they represent equal key values. Reported-by: Noah Misch --- contrib/amcheck/verify_nbtree.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c index 20da4a46ba..ae8012f15b 100644 --- a/contrib/amcheck/verify_nbtree.c +++ b/contrib/amcheck/verify_nbtree.c @@ -1428,6 +1428,7 @@ bt_target_page_check(BtreeCheckState *state) BTScanInsert skey; bool lowersizelimit; ItemPointer scantid; + bool unique_checked = false; CHECK_FOR_INTERRUPTS(); @@ -1774,10 +1775,14 @@ bt_target_page_check(BtreeCheckState *state) * heap tuples visibility. */ if (state->checkunique && state->indexinfo->ii_Unique && - P_ISLEAF(topaque) && !skey->anynullkeys) + P_ISLEAF(topaque) && !skey->anynullkeys && + (BTreeTupleIsPosting(itup) || ItemPointerIsValid(lVis_tid))) + { bt_entry_unique_check(state, itup, state->targetblock, offset, &lVis_i, &lVis_tid, &lVis_offset, &lVis_block); + unique_checked = true; + } if (state->checkunique && state->indexinfo->ii_Unique && P_ISLEAF(topaque) && OffsetNumberNext(offset) <= max) @@ -1805,6 +1810,12 @@ bt_target_page_check(BtreeCheckState *state) lVis_block = InvalidBlockNumber; lVis_offset = InvalidOffsetNumber; } + else if (!unique_checked) + { + bt_entry_unique_check(state, itup, state->targetblock, offset, + &lVis_i, &lVis_tid, &lVis_offset, + &lVis_block); + } skey->scantid = scantid; /* Restore saved scan key state */ } @@ -1889,6 +1900,11 @@ bt_target_page_check(BtreeCheckState *state) /* The first key on the next page is the same */ if (_bt_compare(state->rel, rightkey, state->target, max) == 0 && !rightkey->anynullkeys) { + if (!unique_checked) + bt_entry_unique_check(state, itup, state->targetblock, offset, + &lVis_i, &lVis_tid, &lVis_offset, + &lVis_block); + elog(DEBUG2, "cross page equal keys"); state->target = palloc_btree_page(state, rightblock_number); -- 2.34.1