v36-0005-Fix-for-gin_index_check.patch
application/octet-stream
Filename: v36-0005-Fix-for-gin_index_check.patch
Type: application/octet-stream
Part: 4
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 v36-0005
Subject: Fix for gin_index_check.
| File | + | − |
|---|---|---|
| contrib/amcheck/verify_gin.c | 27 | 16 |
From 330ad2f0fa34e6f2dffe19afa340cd3da2261920 Mon Sep 17 00:00:00 2001
From: reshke kirill <reshke@double.cloud>
Date: Mon, 16 Dec 2024 10:49:43 +0000
Subject: [PATCH v36 5/8] Fix for gin_index_check.
Never explicitly check high key on rightmost page is entry tree.
Its value is not stored explicitly and is equal to infitity.
---
contrib/amcheck/verify_gin.c | 43 ++++++++++++++++++++++--------------
1 file changed, 27 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/verify_gin.c b/contrib/amcheck/verify_gin.c
index 2dc5fbba619..74783af54d4 100644
--- a/contrib/amcheck/verify_gin.c
+++ b/contrib/amcheck/verify_gin.c
@@ -163,6 +163,7 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting
Page page;
OffsetNumber i,
maxoff;
+ BlockNumber rightlink;
CHECK_FOR_INTERRUPTS();
@@ -170,6 +171,7 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting
RBM_NORMAL, strategy);
LockBuffer(buffer, GIN_SHARE);
page = (Page) BufferGetPage(buffer);
+
Assert(GinPageIsData(page));
/* Check that the tree has the same height in all branches */
@@ -234,8 +236,8 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting
* Check that tuples in each page are properly ordered and
* consistent with parent high key
*/
- Assert(GinPageIsData(page));
maxoff = GinPageGetOpaque(page)->maxoff;
+ rightlink = GinPageGetOpaque(page)->rightlink;
elog(DEBUG1, "page blk: %u, type data, maxoff %d", stack->blkno, maxoff);
@@ -273,7 +275,12 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting
*/
bound = *GinDataPageGetRightBound(page);
- if (stack->parentblk != InvalidBlockNumber &&
+ /*
+ * Gin page right bound has sane value if only not a highkey on
+ * rightmost page on level.
+ */
+ if (ItemPointerIsValid(&stack->parentkey) &&
+ rightlink != InvalidBlockNumber &&
!ItemPointerEquals(&stack->parentkey, &bound))
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
@@ -287,11 +294,12 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{
+ GinPostingTreeScanItem *ptr;
PostingItem *posting_item = GinDataPageGetPostingItem(page, i);
/* ItemPointerGetOffsetNumber expects a valid pointer */
if (!(i == maxoff &&
- GinPageGetOpaque(page)->rightlink == InvalidBlockNumber))
+ rightlink == InvalidBlockNumber))
elog(DEBUG3, "key (%u, %u) -> %u",
ItemPointerGetBlockNumber(&posting_item->key),
ItemPointerGetOffsetNumber(&posting_item->key),
@@ -300,8 +308,7 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting
elog(DEBUG3, "key (%u, %u) -> %u",
0, 0, BlockIdGetBlockNumber(&posting_item->child_blkno));
- if (i == maxoff &&
- GinPageGetOpaque(page)->rightlink == InvalidBlockNumber)
+ if (i == maxoff && rightlink == InvalidBlockNumber)
{
/*
* The rightmost item in the tree level has (0, 0) as the
@@ -340,19 +347,23 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting
RelationGetRelationName(rel),
stack->blkno, i)));
- /* If this is an internal page, recurse into the child */
- if (!GinPageIsLeaf(page))
- {
- GinPostingTreeScanItem *ptr;
+ /* This is an internal page, recurse into the child */
+ ptr = (GinPostingTreeScanItem *) palloc(sizeof(GinPostingTreeScanItem));
+ ptr->depth = stack->depth + 1;
- ptr = (GinPostingTreeScanItem *) palloc(sizeof(GinPostingTreeScanItem));
- ptr->depth = stack->depth + 1;
+ /*
+ * Set rightmost parent key to invalid iterm pointer. Its
+ * value is 'Infinity' and not explicitly stored.
+ */
+ if (rightlink == InvalidBlockNumber)
+ ItemPointerSetInvalid(&ptr->parentkey);
+ else
ptr->parentkey = posting_item->key;
- ptr->parentblk = stack->blkno;
- ptr->blkno = BlockIdGetBlockNumber(&posting_item->child_blkno);
- ptr->next = stack->next;
- stack->next = ptr;
- }
+
+ ptr->parentblk = stack->blkno;
+ ptr->blkno = BlockIdGetBlockNumber(&posting_item->child_blkno);
+ ptr->next = stack->next;
+ stack->next = ptr;
}
}
LockBuffer(buffer, GIN_UNLOCK);
--
2.39.3 (Apple Git-145)