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

Commit aac80bf

Browse files
Fix amcheck child check pg_upgrade bug.
Commit d114cc5 overlooked the fact that pg_upgrade'd B-Tree indexes have leaf page high keys whose offset numbers do not match the one from the copy of the tuple one level up (the copy stored with a downlink for leaf page's right sibling page). This led to false positive reports of corruption from bt_index_parent_check() when it was called to verify a pg_upgrade'd index. To fix, skip comparing the offset number on pg_upgrade'd B-Tree indexes. Author: Anastasia Lubennikova <a.lubennikova@postgrespro.ru> Author: Peter Geoghegan <pg@bowt.ie> Reported-By: Andrew Bille <andrewbille@gmail.com> Diagnosed-By: Anastasia Lubennikova <a.lubennikova@postgrespro.ru> Bug: #16619 Discussion: https://postgr.es/m/16619-aaba10f83fdc1c3c@postgresql.org Backpatch: 13-, where child check was enhanced.
1 parent e5fac1c commit aac80bf

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

contrib/amcheck/verify_nbtree.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,14 +1752,36 @@ bt_right_page_check_scankey(BtreeCheckState *state)
17521752
* this function is capable to compare pivot keys on different levels.
17531753
*/
17541754
static bool
1755-
bt_pivot_tuple_identical(IndexTuple itup1, IndexTuple itup2)
1755+
bt_pivot_tuple_identical(bool heapkeyspace, IndexTuple itup1, IndexTuple itup2)
17561756
{
17571757
if (IndexTupleSize(itup1) != IndexTupleSize(itup2))
17581758
return false;
17591759

1760-
if (memcmp(&itup1->t_tid.ip_posid, &itup2->t_tid.ip_posid,
1761-
IndexTupleSize(itup1) - offsetof(ItemPointerData, ip_posid)) != 0)
1762-
return false;
1760+
if (heapkeyspace)
1761+
{
1762+
/*
1763+
* Offset number will contain important information in heapkeyspace
1764+
* indexes: the number of attributes left in the pivot tuple following
1765+
* suffix truncation. Don't skip over it (compare it too).
1766+
*/
1767+
if (memcmp(&itup1->t_tid.ip_posid, &itup2->t_tid.ip_posid,
1768+
IndexTupleSize(itup1) -
1769+
offsetof(ItemPointerData, ip_posid)) != 0)
1770+
return false;
1771+
}
1772+
else
1773+
{
1774+
/*
1775+
* Cannot rely on offset number field having consistent value across
1776+
* levels on pg_upgrade'd !heapkeyspace indexes. Compare contents of
1777+
* tuple starting from just after item pointer (i.e. after block
1778+
* number and offset number).
1779+
*/
1780+
if (memcmp(&itup1->t_info, &itup2->t_info,
1781+
IndexTupleSize(itup1) -
1782+
offsetof(IndexTupleData, t_info)) != 0)
1783+
return false;
1784+
}
17631785

17641786
return true;
17651787
}
@@ -1913,7 +1935,7 @@ bt_child_highkey_check(BtreeCheckState *state,
19131935
rightsplit = P_INCOMPLETE_SPLIT(opaque);
19141936

19151937
/*
1916-
* If we visit page with high key, check that it is be equal to the
1938+
* If we visit page with high key, check that it is equal to the
19171939
* target key next to corresponding downlink.
19181940
*/
19191941
if (!rightsplit && !P_RIGHTMOST(opaque))
@@ -2007,7 +2029,7 @@ bt_child_highkey_check(BtreeCheckState *state,
20072029
itup = state->lowkey;
20082030
}
20092031

2010-
if (!bt_pivot_tuple_identical(highkey, itup))
2032+
if (!bt_pivot_tuple_identical(state->heapkeyspace, highkey, itup))
20112033
{
20122034
ereport(ERROR,
20132035
(errcode(ERRCODE_INDEX_CORRUPTED),

0 commit comments

Comments
 (0)