Skip to content

Commit 63fa0de

Browse files
nbtree VACUUM: cope with topparent inconsistencies.
Avoid "right sibling %u of block %u is not next child" errors when vacuuming a corrupt nbtree index. Just LOG the issue and press on. That way VACUUM will have a decent chance of finishing off all required processing for the index (and for the table as a whole). This is similar to recent work from commit 5abff19, as well as work from commit 5b861ba (later backpatched as commit 43e409c), which taught nbtree VACUUM to keep going when its "re-find" check fails. The hardening added by this commit takes place directly after the "re-find" check, right before the critical section for the first stage of page deletion. Author: Peter Geoghegan <pg@bowt.ie> Discussion: https://postgr.es/m/CAH2-Wz=dayg0vjs4+er84TS9ami=csdzjpuiCGbEw=idhwqhzQ@mail.gmail.com Backpatch: 11- (all supported versions).
1 parent 43b28fc commit 63fa0de

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

src/backend/access/nbtree/nbtpage.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2148,12 +2148,6 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack)
21482148
&topparent, &topparentrightsib))
21492149
return false;
21502150

2151-
/*
2152-
* Check that the parent-page index items we're about to delete/overwrite
2153-
* in subtree parent page contain what we expect. This can fail if the
2154-
* index has become corrupt for some reason. We want to throw any error
2155-
* before entering the critical section --- otherwise it'd be a PANIC.
2156-
*/
21572151
page = BufferGetPage(subtreeparent);
21582152
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
21592153

@@ -2171,15 +2165,29 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack)
21712165
nextoffset = OffsetNumberNext(poffset);
21722166
itemid = PageGetItemId(page, nextoffset);
21732167
itup = (IndexTuple) PageGetItem(page, itemid);
2168+
2169+
/*
2170+
* Check that the parent-page index items we're about to delete/overwrite
2171+
* in subtree parent page contain what we expect. This can fail if the
2172+
* index has become corrupt for some reason. When that happens we back
2173+
* out of deletion of the leafbuf subtree. (This is just like the case
2174+
* where _bt_lock_subtree_parent() cannot "re-find" leafbuf's downlink.)
2175+
*/
21742176
if (BTreeTupleGetDownLink(itup) != topparentrightsib)
2175-
ereport(ERROR,
2177+
{
2178+
ereport(LOG,
21762179
(errcode(ERRCODE_INDEX_CORRUPTED),
21772180
errmsg_internal("right sibling %u of block %u is not next child %u of block %u in index \"%s\"",
21782181
topparentrightsib, topparent,
21792182
BTreeTupleGetDownLink(itup),
21802183
BufferGetBlockNumber(subtreeparent),
21812184
RelationGetRelationName(rel))));
21822185

2186+
_bt_relbuf(rel, subtreeparent);
2187+
Assert(false);
2188+
return false;
2189+
}
2190+
21832191
/*
21842192
* Any insert which would have gone on the leaf block will now go to its
21852193
* right sibling. In other words, the key space moves right.
@@ -2834,6 +2842,7 @@ _bt_lock_subtree_parent(Relation rel, BlockNumber child, BTStack stack,
28342842
(errcode(ERRCODE_INDEX_CORRUPTED),
28352843
errmsg_internal("failed to re-find parent key in index \"%s\" for deletion target page %u",
28362844
RelationGetRelationName(rel), child)));
2845+
Assert(false);
28372846
return false;
28382847
}
28392848

0 commit comments

Comments
 (0)