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

Lines changed: 16 additions & 6 deletions
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)
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