Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit188dad6

Browse files
nbtree VACUUM: cope with right sibling link corruption.
Avoid "right sibling's left-link doesn't match" errors when vacuuming acorrupt nbtree index. Just LOG the issue and press on. That way VACUUMwill have a decent chance of finishing off all required processing forthe index (and for the table as a whole).This error was seen in the field from time to time (it's more than atheoretical risk), so giving VACUUM the ability to press on like thishas real value. Nothing short of a REINDEX is expected to fix theunderlying index corruption, so giving up (by throwing an error) risksmaking a bad situation far worse. Anything that blocks forward progressby VACUUM like this might go unnoticed for a long time. This couldeventually lead to a wraparound/xidStopLimit outage.Note that _bt_unlink_halfdead_page() has always been able to bail onpage deletion when the target page's left sibling page was in aninconsistent state. It now does the same thing (returns false to backout of the second phase of deletion) when it notices sibling linkcorruption in the target page's right sibling page.This is similar to the work from commit5b861ba (later backpatched ascommit43e409c), which taught nbtree to press on with vacuuming anindex when page deletion fails to "re-find" a downlink in the targetpage's parent page. The "re-find" check seems to make VACUUM bail onpage deletion more often in practice, but there is no reason to take anychances here.Author: Peter Geoghegan <pg@bowt.ie>Reviewed-By: Heikki Linnakangas <hlinnaka@iki.fi>Discussion:https://postgr.es/m/CAH2-Wzko2q2kP1+UvgJyP9g0mF4hopK0NtQZcxwvMv9_ytGhkQ@mail.gmail.comBackpatch: 11- (all supported versions).
1 parentff77d86 commit188dad6

File tree

1 file changed

+36
-11
lines changed

1 file changed

+36
-11
lines changed

‎src/backend/access/nbtree/nbtpage.c

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,13 +1912,6 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
19121912
leftsib=opaque->btpo_next;
19131913
_bt_relbuf(rel,lbuf);
19141914

1915-
/*
1916-
* It'd be good to check for interrupts here, but it's not easy to
1917-
* do so because a lock is always held. This block isn't
1918-
* frequently reached, so hopefully the consequences of not
1919-
* checking interrupts aren't too bad.
1920-
*/
1921-
19221915
if (leftsib==P_NONE)
19231916
{
19241917
elog(LOG,"no left sibling (concurrent deletion?) of block %u in \"%s\"",
@@ -1937,6 +1930,9 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
19371930
}
19381931
return false;
19391932
}
1933+
1934+
CHECK_FOR_INTERRUPTS();
1935+
19401936
lbuf=_bt_getbuf(rel,leftsib,BT_WRITE);
19411937
page=BufferGetPage(lbuf);
19421938
opaque= (BTPageOpaque)PageGetSpecialPointer(page);
@@ -1997,11 +1993,40 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
19971993
rbuf=_bt_getbuf(rel,rightsib,BT_WRITE);
19981994
page=BufferGetPage(rbuf);
19991995
opaque= (BTPageOpaque)PageGetSpecialPointer(page);
1996+
1997+
/*
1998+
* Validate target's right sibling page. Its left link must point back to
1999+
* the target page.
2000+
*/
20002001
if (opaque->btpo_prev!=target)
2001-
elog(ERROR,"right sibling's left-link doesn't match: "
2002-
"block %u links to %u instead of expected %u in index \"%s\"",
2003-
rightsib,opaque->btpo_prev,target,
2004-
RelationGetRelationName(rel));
2002+
{
2003+
/*
2004+
* This is known to fail in the field; sibling link corruption is
2005+
* relatively common. Press on with vacuuming rather than just
2006+
* throwing an ERROR (same approach used for left-sibling's-right-link
2007+
* validation check a moment ago).
2008+
*/
2009+
ereport(LOG,
2010+
(errcode(ERRCODE_INDEX_CORRUPTED),
2011+
errmsg_internal("right sibling's left-link doesn't match: "
2012+
"right sibling %u of target %u with leafblkno %u "
2013+
"and scanblkno %u spuriously links to non-target %u "
2014+
"on level %u of index \"%s\"",
2015+
rightsib,target,leafblkno,
2016+
scanblkno,opaque->btpo_prev,
2017+
targetlevel,RelationGetRelationName(rel))));
2018+
2019+
/* Must release all pins and locks on failure exit */
2020+
if (BufferIsValid(lbuf))
2021+
_bt_relbuf(rel,lbuf);
2022+
_bt_relbuf(rel,rbuf);
2023+
_bt_relbuf(rel,buf);
2024+
if (target!=leafblkno)
2025+
_bt_relbuf(rel,leafbuf);
2026+
2027+
return false;
2028+
}
2029+
20052030
rightsib_is_rightmost=P_RIGHTMOST(opaque);
20062031
*rightsib_empty= (P_FIRSTDATAKEY(opaque)>PageGetMaxOffsetNumber(page));
20072032

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp