diff options
Diffstat (limited to 'src/backend/access/nbtree/nbtpage.c')
-rw-r--r-- | src/backend/access/nbtree/nbtpage.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index 378c5f9d36f..03b8ca3b4ab 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtpage.c,v 1.81.4.1 2005/05/07 21:32:53 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtpage.c,v 1.81.4.2 2006/11/01 19:50:08 tgl Exp $ * * NOTES * Postgres btree pages look like ordinary relation pages. The opaque @@ -867,16 +867,28 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full) rbuf = _bt_getbuf(rel, rightsib, BT_WRITE); /* - * Next find and write-lock the current parent of the target page. - * This is essentially the same as the corresponding step of - * splitting. + * Next find and write-lock the current parent of the target page. This is + * essentially the same as the corresponding step of splitting. However, + * it's possible for the search to fail (for reasons explained in README). + * If that happens, we recover by searching the whole parent level, which + * is a tad inefficient but doesn't happen often enough to be a problem. */ ItemPointerSet(&(stack->bts_btitem.bti_itup.t_tid), target, P_HIKEY); pbuf = _bt_getstackbuf(rel, stack, BT_WRITE); if (pbuf == InvalidBuffer) - elog(ERROR, "failed to re-find parent key in \"%s\"", - RelationGetRelationName(rel)); + { + /* Find the leftmost page in the parent level */ + pbuf = _bt_get_endpoint(rel, opaque->btpo.level + 1, false); + stack->bts_blkno = BufferGetBlockNumber(pbuf); + stack->bts_offset = InvalidOffsetNumber; + _bt_relbuf(rel, pbuf); + /* and repeat search from there */ + pbuf = _bt_getstackbuf(rel, stack, BT_WRITE); + if (pbuf == InvalidBuffer) + elog(ERROR, "failed to re-find parent key in \"%s\" for deletion target page %u", + RelationGetRelationName(rel), target); + } parent = stack->bts_blkno; poffset = stack->bts_offset; |