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

Commit 97e5b00

Browse files
committed
amcheck: Report an error when the next page to a leaf is not a leaf
This is a very unlikely condition during checking a B-tree unique constraint, meaning that the index structure is violated badly, and we shouldn't continue checking to avoid endless loops, etc. So it's worth immediately throwing an error. Reported-by: Peter Geoghegan Discussion: https://postgr.es/m/CAH2-Wzk%2B2116uOXdOViA27SHcr31WKPgmjsxXLBs_aTxAeThzg%40mail.gmail.com Author: Pavel Borisov
1 parent 0b5c161 commit 97e5b00

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

contrib/amcheck/verify_nbtree.c

+16-6
Original file line numberDiff line numberDiff line change
@@ -1831,7 +1831,6 @@ bt_target_page_check(BtreeCheckState *state)
18311831
if (offset == max)
18321832
{
18331833
BTScanInsert rightkey;
1834-
BlockNumber rightblock_number;
18351834

18361835
/* first offset on a right index page (log only) */
18371836
OffsetNumber rightfirstoffset = InvalidOffsetNumber;
@@ -1876,10 +1875,11 @@ bt_target_page_check(BtreeCheckState *state)
18761875
* If index has unique constraint make sure that no more than one
18771876
* found equal items is visible.
18781877
*/
1879-
rightblock_number = topaque->btpo_next;
18801878
if (state->checkunique && state->indexinfo->ii_Unique &&
1881-
rightkey && P_ISLEAF(topaque) && rightblock_number != P_NONE)
1879+
rightkey && P_ISLEAF(topaque) && !P_RIGHTMOST(topaque))
18821880
{
1881+
BlockNumber rightblock_number = topaque->btpo_next;
1882+
18831883
elog(DEBUG2, "check cross page unique condition");
18841884

18851885
/*
@@ -1899,9 +1899,19 @@ bt_target_page_check(BtreeCheckState *state)
18991899
rightblock_number);
19001900
topaque = BTPageGetOpaque(rightpage);
19011901

1902-
if (P_IGNORE(topaque) || !P_ISLEAF(topaque))
1903-
break;
1904-
1902+
if (P_IGNORE(topaque))
1903+
{
1904+
if (unlikely(!P_ISLEAF(topaque)))
1905+
ereport(ERROR,
1906+
(errcode(ERRCODE_INDEX_CORRUPTED),
1907+
errmsg("right block of leaf block is non-leaf for index \"%s\"",
1908+
RelationGetRelationName(state->rel)),
1909+
errdetail_internal("Block=%u page lsn=%X/%X.",
1910+
state->targetblock,
1911+
LSN_FORMAT_ARGS(state->targetlsn))));
1912+
else
1913+
break;
1914+
}
19051915
itemid = PageGetItemIdCareful(state, rightblock_number,
19061916
rightpage,
19071917
rightfirstoffset);

0 commit comments

Comments
 (0)