Fix amcheck child check pg_upgrade bug.
Commit d114cc53 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.
This commit is contained in:
parent
e5fac1cb19
commit
aac80bfcdd
@ -1752,14 +1752,36 @@ bt_right_page_check_scankey(BtreeCheckState *state)
|
||||
* this function is capable to compare pivot keys on different levels.
|
||||
*/
|
||||
static bool
|
||||
bt_pivot_tuple_identical(IndexTuple itup1, IndexTuple itup2)
|
||||
bt_pivot_tuple_identical(bool heapkeyspace, IndexTuple itup1, IndexTuple itup2)
|
||||
{
|
||||
if (IndexTupleSize(itup1) != IndexTupleSize(itup2))
|
||||
return false;
|
||||
|
||||
if (memcmp(&itup1->t_tid.ip_posid, &itup2->t_tid.ip_posid,
|
||||
IndexTupleSize(itup1) - offsetof(ItemPointerData, ip_posid)) != 0)
|
||||
return false;
|
||||
if (heapkeyspace)
|
||||
{
|
||||
/*
|
||||
* Offset number will contain important information in heapkeyspace
|
||||
* indexes: the number of attributes left in the pivot tuple following
|
||||
* suffix truncation. Don't skip over it (compare it too).
|
||||
*/
|
||||
if (memcmp(&itup1->t_tid.ip_posid, &itup2->t_tid.ip_posid,
|
||||
IndexTupleSize(itup1) -
|
||||
offsetof(ItemPointerData, ip_posid)) != 0)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Cannot rely on offset number field having consistent value across
|
||||
* levels on pg_upgrade'd !heapkeyspace indexes. Compare contents of
|
||||
* tuple starting from just after item pointer (i.e. after block
|
||||
* number and offset number).
|
||||
*/
|
||||
if (memcmp(&itup1->t_info, &itup2->t_info,
|
||||
IndexTupleSize(itup1) -
|
||||
offsetof(IndexTupleData, t_info)) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1913,7 +1935,7 @@ bt_child_highkey_check(BtreeCheckState *state,
|
||||
rightsplit = P_INCOMPLETE_SPLIT(opaque);
|
||||
|
||||
/*
|
||||
* If we visit page with high key, check that it is be equal to the
|
||||
* If we visit page with high key, check that it is equal to the
|
||||
* target key next to corresponding downlink.
|
||||
*/
|
||||
if (!rightsplit && !P_RIGHTMOST(opaque))
|
||||
@ -2007,7 +2029,7 @@ bt_child_highkey_check(BtreeCheckState *state,
|
||||
itup = state->lowkey;
|
||||
}
|
||||
|
||||
if (!bt_pivot_tuple_identical(highkey, itup))
|
||||
if (!bt_pivot_tuple_identical(state->heapkeyspace, highkey, itup))
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INDEX_CORRUPTED),
|
||||
|
Loading…
x
Reference in New Issue
Block a user