Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf8cce4a

Browse files
Further harden nbtree posting split code.
Add more defensive checks around posting list split code. These shoulddetect corruption involving duplicate table TIDs earlier and morereliably than any existing check.Follow up to commit8f72bba.Discussion:https://postgr.es/m/CAH2-WzkrSY_kjyd1_M5xJK1uM0govJXMxPn8JUSvwcUOiHuWVw@mail.gmail.comBackpatch: 13-, where nbtree deduplication was introduced.
1 parentdd11188 commitf8cce4a

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

‎src/backend/access/nbtree/nbtinsert.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,10 +1157,30 @@ _bt_insertonpg(Relation rel,
11571157
* its post-split version is treated as an extra step in either the
11581158
* insert or page split critical section.
11591159
*/
1160-
Assert(P_ISLEAF(lpageop)&& !ItemIdIsDead(itemid));
1161-
Assert(itup_key->heapkeyspace&&itup_key->allequalimage);
1160+
Assert(P_ISLEAF(lpageop)&&
1161+
itup_key->heapkeyspace&&itup_key->allequalimage);
11621162
oposting= (IndexTuple)PageGetItem(page,itemid);
11631163

1164+
/*
1165+
* postingoff value comes from earlier call to _bt_binsrch_posting().
1166+
* Its binary search might think that a plain tuple must be a posting
1167+
* list tuple that needs to be split. This can happen with corruption
1168+
* involving an existing plain tuple that is a duplicate of the new
1169+
* item, up to and including its table TID. Check for that here in
1170+
* passing.
1171+
*
1172+
* Also verify that our caller has made sure that the existing posting
1173+
* list tuple does not have its LP_DEAD bit set.
1174+
*/
1175+
if (!BTreeTupleIsPosting(oposting)||ItemIdIsDead(itemid))
1176+
ereport(ERROR,
1177+
(errcode(ERRCODE_INDEX_CORRUPTED),
1178+
errmsg_internal("table tid from new index tuple (%u,%u) overlaps with invalid duplicate tuple at offset %u of block %u in index \"%s\"",
1179+
ItemPointerGetBlockNumber(&itup->t_tid),
1180+
ItemPointerGetOffsetNumber(&itup->t_tid),
1181+
BufferGetBlockNumber(buf),newitemoff,
1182+
RelationGetRelationName(rel))));
1183+
11641184
/* use a mutable copy of itup as our itup from here on */
11651185
origitup=itup;
11661186
itup=CopyIndexTuple(origitup);

‎src/backend/access/nbtree/nbtsearch.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,24 @@ _bt_binsrch_insert(Relation rel, BTInsertState insertstate)
530530
* infrequently.
531531
*/
532532
if (unlikely(result==0&&key->scantid!=NULL))
533+
{
534+
/*
535+
* postingoff should never be set more than once per leaf page
536+
* binary search. That would mean that there are duplicate table
537+
* TIDs in the index, which is never okay. Check for that here.
538+
*/
539+
if (insertstate->postingoff!=0)
540+
ereport(ERROR,
541+
(errcode(ERRCODE_INDEX_CORRUPTED),
542+
errmsg_internal("table tid from new index tuple (%u,%u) cannot find insert offset between offsets %u and %u of block %u in index \"%s\"",
543+
ItemPointerGetBlockNumber(key->scantid),
544+
ItemPointerGetOffsetNumber(key->scantid),
545+
low,stricthigh,
546+
BufferGetBlockNumber(insertstate->buf),
547+
RelationGetRelationName(rel))));
548+
533549
insertstate->postingoff=_bt_binsrch_posting(key,page,mid);
550+
}
534551
}
535552

536553
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp