Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 365bf48

Browse files
michail-nikolaevCommitfest Bot
authored and
Commitfest Bot
committed
Support snapshot resets in concurrent builds of unique indexes
Previously, concurrent builds if unique index used a fixed snapshot for the entire scan to ensure proper uniqueness checks. Now reset snapshots periodically during concurrent unique index builds, while still maintaining uniqueness by: - ignoring SnapshotSelf dead tuples during uniqueness checks in tuplesort as not a guarantee, but a fail-fast mechanics - adding a uniqueness check in _bt_load that detects multiple alive tuples with the same key values as a guarantee of correctness Tuples are SnapshotSelf tested only in the case of equal index key values, overwise _bt_load works like before.
1 parent 36764b2 commit 365bf48

File tree

13 files changed

+264
-94
lines changed

13 files changed

+264
-94
lines changed

src/backend/access/heap/README.HOT

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -386,12 +386,12 @@ have the HOT-safety property enforced before we start to build the new
386386
index.
387387

388388
After waiting for transactions which had the table open, we build the index
389-
for all rows that are valid in a fresh snapshot. Any tuples visible in the
390-
snapshot will have only valid forward-growing HOT chains. (They might have
391-
older HOT updates behind them which are broken, but this is OK for the same
392-
reason it's OK in a regular index build.) As above, we point the index
393-
entry at the root of the HOT-update chain but we use the key value from the
394-
live tuple.
389+
for all rows that are valid in a fresh snapshot, which is updated every so
390+
often. Any tuples visible in the snapshot will have only valid forward-growing
391+
HOT chains. (They might have older HOT updates behind them which are broken,
392+
but this is OK for the same reason it's OK in a regular index build.)
393+
As above, we point the index entry at the root of the HOT-update chain but we
394+
use the key value from the live tuple.
395395

396396
We mark the index open for inserts (but still not ready for reads) then
397397
we again wait for transactions which have the table open. Then we take

src/backend/access/heap/heapam_handler.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,15 +1236,15 @@ heapam_index_build_range_scan(Relation heapRelation,
12361236
* qual checks (because we have to index RECENTLY_DEAD tuples). In a
12371237
* concurrent build, or during bootstrap, we take a regular MVCC snapshot
12381238
* and index whatever's live according to that while that snapshot is reset
1239-
* every so often (in case of non-unique index).
1239+
* every so often.
12401240
*/
12411241
OldestXmin = InvalidTransactionId;
12421242

12431243
/*
1244-
* For unique index we need consistent snapshot for the whole scan.
1244+
* For concurrent builds of non-system indexes, we may want to periodically
1245+
* reset snapshots to allow vacuum to clean up tuples.
12451246
*/
12461247
reset_snapshots = indexInfo->ii_Concurrent &&
1247-
!indexInfo->ii_Unique &&
12481248
!is_system_catalog; /* just for the case */
12491249

12501250
/* okay to ignore lazy VACUUMs here */

src/backend/access/nbtree/nbtdedup.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ _bt_dedup_pass(Relation rel, Buffer buf, IndexTuple newitem, Size newitemsz,
148148
_bt_dedup_start_pending(state, itup, offnum);
149149
}
150150
else if (state->deduplicate &&
151-
_bt_keep_natts_fast(rel, state->base, itup) > nkeyatts &&
151+
_bt_keep_natts_fast(rel, state->base, itup, NULL) > nkeyatts &&
152152
_bt_dedup_save_htid(state, itup))
153153
{
154154
/*
@@ -374,7 +374,7 @@ _bt_bottomupdel_pass(Relation rel, Buffer buf, Relation heapRel,
374374
/* itup starts first pending interval */
375375
_bt_dedup_start_pending(state, itup, offnum);
376376
}
377-
else if (_bt_keep_natts_fast(rel, state->base, itup) > nkeyatts &&
377+
else if (_bt_keep_natts_fast(rel, state->base, itup, NULL) > nkeyatts &&
378378
_bt_dedup_save_htid(state, itup))
379379
{
380380
/* Tuple is equal; just added its TIDs to pending interval */
@@ -789,12 +789,12 @@ _bt_do_singleval(Relation rel, Page page, BTDedupState state,
789789
itemid = PageGetItemId(page, minoff);
790790
itup = (IndexTuple) PageGetItem(page, itemid);
791791

792-
if (_bt_keep_natts_fast(rel, newitem, itup) > nkeyatts)
792+
if (_bt_keep_natts_fast(rel, newitem, itup, NULL) > nkeyatts)
793793
{
794794
itemid = PageGetItemId(page, PageGetMaxOffsetNumber(page));
795795
itup = (IndexTuple) PageGetItem(page, itemid);
796796

797-
if (_bt_keep_natts_fast(rel, newitem, itup) > nkeyatts)
797+
if (_bt_keep_natts_fast(rel, newitem, itup, NULL) > nkeyatts)
798798
return true;
799799
}
800800

0 commit comments

Comments
 (0)