From 1d0969b8b11a62226f4441d1b3a335832fdffac7 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Sat, 4 May 2019 12:27:31 -0700 Subject: [PATCH] Remove nbtree half-dead internal page check. Internal nbtree pages are never marked half-dead by VACUUM following commit efada2b8e92, which made nbtree page deletion more robust. It follows that VACUUM cannot possibly benefit from checking if an internal page is half-dead as part of assessing if it's safe to delete the internal page to its left. The same VACUUM operation will report the same half-dead internal page as corrupt when it processes it directly a little later on. Remove the useless check, and add a comment explaining why it's safe to rely on a similar leaf-level check to transitively detect if internal pages are pending deletion. Both checks were added by bugfix commit 8da31837803 a couple of months after commit efada2b8e92 went in, following a report of a failing sanity check. Discussion: https://postgr.es/m/CAH2-Wz=_Xvv8byzK_LvY4ci76OgsHCQzoKF7We8yG9waO7j6rA@mail.gmail.com --- src/backend/access/nbtree/nbtpage.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index 8ade165f7a..84011438a0 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -1301,17 +1301,6 @@ _bt_lock_branch_parent(Relation rel, BlockNumber child, BTStack stack, _bt_relbuf(rel, lbuf); } - /* - * Perform the same check on this internal level that - * _bt_mark_page_halfdead performed on the leaf level. - */ - if (_bt_is_page_halfdead(rel, *rightsib)) - { - elog(DEBUG1, "could not delete page %u because its right sibling %u is half-dead", - parent, *rightsib); - return false; - } - return _bt_lock_branch_parent(rel, parent, stack->bts_parent, topparent, topoff, target, rightsib); } @@ -1622,6 +1611,15 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack) * be deleted too, and the same condition applies recursively to it. We * have to check this condition all the way up before trying to delete, * and lock the final parent of the to-be-deleted branch. + * + * However, we don't need to repeat the above _bt_is_page_halfdead() check + * on parent/ancestor pages because of the rightmost restriction. The + * check will apply to a right "cousin" page rather than a simple right + * sibling page in cases where we actually go on to perform internal page + * deletion. The cousin page is representative of the left edge of the + * subtree to the right as a whole. (Besides, internal pages are never + * marked half-dead, so it isn't even possible to directly assess if an + * internal page is part of a to-be-deleted branch.) */ rightsib = leafrightsib; target = leafblkno; -- 2.17.1