Skip to content

Commit 74eb217

Browse files
Invalidate binary search bounds consistently.
_bt_check_unique() failed to invalidate binary search bounds in the event of a live conflict following commit e5adcb7. This resulted in problems after waiting for the conflicting xact to commit or abort. The subsequent call to _bt_check_unique() would restore the initial binary search bounds, rather than starting a new search. Fix by explicitly invalidating bounds when it becomes clear that there is a live conflict that insertion will have to wait to resolve. Ashutosh Sharma, with a few additional tweaks by me. Author: Ashutosh Sharma Reported-By: Ashutosh Sharma Diagnosed-By: Ashutosh Sharma Discussion: https://postgr.es/m/CAE9k0PnQp-qr-UYKMSCzdC2FBzdE4wKP41hZrZvvP26dKLonLg@mail.gmail.com
1 parent 87e16db commit 74eb217

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

src/backend/access/nbtree/nbtinsert.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel,
347347
* This also saves the binary search bounds in insertstate. We use them
348348
* in the fastpath below, but also in the _bt_findinsertloc() call later.
349349
*/
350+
Assert(!insertstate->bounds_valid);
350351
offset = _bt_binsrch_insert(rel, insertstate);
351352

352353
/*
@@ -447,7 +448,8 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel,
447448
* check, then don't bother checking if the tuple is being
448449
* updated in another transaction. Just return the fact
449450
* that it is a potential conflict and leave the full
450-
* check till later.
451+
* check till later. Don't invalidate binary search
452+
* bounds.
451453
*/
452454
if (checkUnique == UNIQUE_CHECK_PARTIAL)
453455
{
@@ -470,6 +472,8 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel,
470472
_bt_relbuf(rel, nbuf);
471473
/* Tell _bt_doinsert to wait... */
472474
*speculativeToken = SnapshotDirty.speculativeToken;
475+
/* Caller releases lock on buf immediately */
476+
insertstate->bounds_valid = false;
473477
return xwait;
474478
}
475479

@@ -526,6 +530,7 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel,
526530
_bt_relbuf(rel, nbuf);
527531
_bt_relbuf(rel, insertstate->buf);
528532
insertstate->buf = InvalidBuffer;
533+
insertstate->bounds_valid = false;
529534

530535
{
531536
Datum values[INDEX_MAX_KEYS];
@@ -601,6 +606,7 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel,
601606
}
602607
maxoff = PageGetMaxOffsetNumber(page);
603608
offset = P_FIRSTDATAKEY(opaque);
609+
/* Don't invalidate binary search bounds */
604610
}
605611
}
606612

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy