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

Commit c287f58

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 17280b3 commit c287f58

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
@@ -1624,14 +1624,36 @@ bt_right_page_check_scankey(BtreeCheckState *state)
16241624
* this function is capable to compare pivot keys on different levels.
16251625
*/
16261626
static bool
1627-
bt_pivot_tuple_identical(IndexTuple itup1, IndexTuple itup2)
1627+
bt_pivot_tuple_identical(bool heapkeyspace, IndexTuple itup1, IndexTuple itup2)
16281628
{
16291629
if (IndexTupleSize(itup1) != IndexTupleSize(itup2))
16301630
return false;
16311631

1632-
if (memcmp(&itup1->t_tid.ip_posid, &itup2->t_tid.ip_posid,
1633-
IndexTupleSize(itup1) - offsetof(ItemPointerData, ip_posid)) != 0)
1634-
return false;
1632+
if (heapkeyspace)
1633+
{
1634+
/*
1635+
* Offset number will contain important information in heapkeyspace
1636+
* indexes: the number of attributes left in the pivot tuple following
1637+
* suffix truncation. Don't skip over it (compare it too).
1638+
*/
1639+
if (memcmp(&itup1->t_tid.ip_posid, &itup2->t_tid.ip_posid,
1640+
IndexTupleSize(itup1) -
1641+
offsetof(ItemPointerData, ip_posid)) != 0)
1642+
return false;
1643+
}
1644+
else
1645+
{
1646+
/*
1647+
* Cannot rely on offset number field having consistent value across
1648+
* levels on pg_upgrade'd !heapkeyspace indexes. Compare contents of
1649+
* tuple starting from just after item pointer (i.e. after block
1650+
* number and offset number).
1651+
*/
1652+
if (memcmp(&itup1->t_info, &itup2->t_info,
1653+
IndexTupleSize(itup1) -
1654+
offsetof(IndexTupleData, t_info)) != 0)
1655+
return false;
1656+
}
16351657

16361658
return true;
16371659
}
@@ -1785,7 +1807,7 @@ bt_child_highkey_check(BtreeCheckState *state,
17851807
rightsplit = P_INCOMPLETE_SPLIT(opaque);
17861808

17871809
/*
1788-
* If we visit page with high key, check that it is be equal to the
1810+
* If we visit page with high key, check that it is equal to the
17891811
* target key next to corresponding downlink.
17901812
*/
17911813
if (!rightsplit && !P_RIGHTMOST(opaque))
@@ -1879,7 +1901,7 @@ bt_child_highkey_check(BtreeCheckState *state,
18791901
itup = state->lowkey;
18801902
}
18811903

1882-
if (!bt_pivot_tuple_identical(highkey, itup))
1904+
if (!bt_pivot_tuple_identical(state->heapkeyspace, highkey, itup))
18831905
{
18841906
ereport(ERROR,
18851907
(errcode(ERRCODE_INDEX_CORRUPTED),

0 commit comments

Comments
 (0)