v2-0004-amcheck-Report-an-error-when-the-next-page-to-a-l.patch
application/octet-stream
Filename: v2-0004-amcheck-Report-an-error-when-the-next-page-to-a-l.patch
Type: application/octet-stream
Part: 3
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v2-0004
Subject: amcheck: Report an error when the next page to a leaf is not a leaf
| File | + | − |
|---|---|---|
| contrib/amcheck/verify_nbtree.c | 16 | 6 |
From 9b36cf33f719107c899863f15ed5d0938a99b029 Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Fri, 10 May 2024 03:07:22 +0300
Subject: [PATCH v2 4/4] 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
---
contrib/amcheck/verify_nbtree.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c
index 977f8b6799d..e9bbc18c4a5 100644
--- a/contrib/amcheck/verify_nbtree.c
+++ b/contrib/amcheck/verify_nbtree.c
@@ -1849,7 +1849,6 @@ bt_target_page_check(BtreeCheckState *state)
if (offset == max)
{
BTScanInsert rightkey;
- BlockNumber rightblock_number;
/* first offset on a right index page (log only) */
OffsetNumber rightfirstoffset = InvalidOffsetNumber;
@@ -1894,10 +1893,11 @@ bt_target_page_check(BtreeCheckState *state)
* If index has unique constraint make sure that no more than one
* found equal items is visible.
*/
- rightblock_number = topaque->btpo_next;
if (state->checkunique && state->indexinfo->ii_Unique &&
- rightkey && P_ISLEAF(topaque) && rightblock_number != P_NONE)
+ rightkey && P_ISLEAF(topaque) && !P_RIGHTMOST(topaque))
{
+ BlockNumber rightblock_number = topaque->btpo_next;
+
elog(DEBUG2, "check cross page unique condition");
/*
@@ -1924,9 +1924,19 @@ bt_target_page_check(BtreeCheckState *state)
rightblock_number);
topaque = BTPageGetOpaque(rightpage);
- if (P_IGNORE(topaque) || !P_ISLEAF(topaque))
- break;
-
+ if (P_IGNORE(topaque))
+ {
+ if (unlikely(!P_ISLEAF(topaque)))
+ ereport(ERROR,
+ (errcode(ERRCODE_INDEX_CORRUPTED),
+ errmsg("right block of leaf block is non-leaf for index \"%s\"",
+ RelationGetRelationName(state->rel)),
+ errdetail_internal("Block=%u page lsn=%X/%X.",
+ state->targetblock,
+ LSN_FORMAT_ARGS(state->targetlsn))));
+ else
+ break;
+ }
itemid = PageGetItemIdCareful(state, rightblock_number,
rightpage,
rightfirstoffset);
--
2.39.3 (Apple Git-145)