mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Fix "failed to re-find parent key" btree VACUUM failure by revising page
deletion code to avoid the case where an upper-level btree page remains "half dead" for a significant period of time, and to block insertions into a key range that is in process of being re-assigned to the right sibling of the deleted page's parent. This prevents the scenario reported by Ed L. wherein index keys could become out-of-order in the grandparent index level. Since this is a moderately invasive fix, I'm applying it only to HEAD. The bug exists back to 7.4, but the back branches will get a different patch.
This commit is contained in:
@ -12,7 +12,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.152 2006/10/04 00:29:49 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.153 2006/11/01 19:43:17 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -804,8 +804,7 @@ restart:
|
||||
if (blkno != orig_blkno)
|
||||
{
|
||||
if (_bt_page_recyclable(page) ||
|
||||
P_ISDELETED(opaque) ||
|
||||
(opaque->btpo_flags & BTP_HALF_DEAD) ||
|
||||
P_IGNORE(opaque) ||
|
||||
!P_ISLEAF(opaque) ||
|
||||
opaque->btpo_cycleid != vstate->cycleid)
|
||||
{
|
||||
@ -828,7 +827,7 @@ restart:
|
||||
/* Already deleted, but can't recycle yet */
|
||||
stats->pages_deleted++;
|
||||
}
|
||||
else if (opaque->btpo_flags & BTP_HALF_DEAD)
|
||||
else if (P_ISHALFDEAD(opaque))
|
||||
{
|
||||
/* Half-dead, try to delete */
|
||||
delete_now = true;
|
||||
@ -939,7 +938,7 @@ restart:
|
||||
MemoryContextReset(vstate->pagedelcontext);
|
||||
oldcontext = MemoryContextSwitchTo(vstate->pagedelcontext);
|
||||
|
||||
ndel = _bt_pagedel(rel, buf, info->vacuum_full);
|
||||
ndel = _bt_pagedel(rel, buf, NULL, info->vacuum_full);
|
||||
|
||||
/* count only this page, else may double-count parent */
|
||||
if (ndel)
|
||||
|
Reference in New Issue
Block a user