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

Commit 5f0762f

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 05ffc1f commit 5f0762f

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
@@ -2147,12 +2147,6 @@ _bt_mark_page_halfdead(Relation rel, Relation heaprel, Buffer leafbuf,
21472147
&topparent, &topparentrightsib))
21482148
return false;
21492149

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

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

2185+
_bt_relbuf(rel, subtreeparent);
2186+
Assert(false);
2187+
return false;
2188+
}
2189+
21822190
/*
21832191
* Any insert which would have gone on the leaf block will now go to its
21842192
* right sibling. In other words, the key space moves right.
@@ -2834,6 +2842,7 @@ _bt_lock_subtree_parent(Relation rel, Relation heaprel, BlockNumber child,
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)