From 598a12722ac117bb0286c0a614274bf6763f1c43 Mon Sep 17 00:00:00 2001 From: "Vadim B. Mikheev" Date: Mon, 29 Jan 2001 07:28:17 +0000 Subject: [PATCH] Call _bt_fixroot() from _bt_insertonpg. --- src/backend/access/nbtree/nbtinsert.c | 62 +++++++++++++++++++++++++-- src/backend/access/nbtree/nbtpage.c | 3 +- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index 8f23e16992..76d2d9ff86 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.77 2001/01/26 01:24:31 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.78 2001/01/29 07:28:16 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -34,7 +34,10 @@ typedef struct int best_delta; /* best size delta so far */ } FindSplitData; +extern bool FixBTree; + Buffer _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release); +static void _bt_fixtree(Relation rel, BlockNumber blkno, BTStack stack); static Buffer _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf); @@ -477,10 +480,55 @@ _bt_insertonpg(Relation rel, BTItem ritem; Buffer pbuf; - /* Set up a phony stack entry if we haven't got a real one */ + /* If root page was splitted */ if (stack == (BTStack) NULL) { elog(DEBUG, "btree: concurrent ROOT page split"); + /* + * If root page splitter failed to create new root page + * then old root' btpo_parent still points to metapage. + * We have to fix root page in this case. + */ + if (lpageop->btpo_parent == BTREE_METAPAGE) + { + if (!FixBTree) + elog(ERROR, "bt_insertonpg: no root page found"); + _bt_wrtbuf(rel, rbuf); + _bt_wrtnorelbuf(rel, buf); + while(! P_LEFTMOST(lpageop)) + { + BlockNumber blkno = lpageop->btpo_prev; + LockBuffer(buf, BUFFER_LOCK_UNLOCK); + ReleaseBuffer(buf); + buf = _bt_getbuf(rel, blkno, BT_WRITE); + page = BufferGetPage(buf); + lpageop = (BTPageOpaque) PageGetSpecialPointer(page); + /* + * If someone else already created parent pages + * then it's time for _bt_fixtree() to check upper + * levels and fix them, if required. + */ + if (lpageop->btpo_parent != BTREE_METAPAGE) + { + blkno = lpageop->btpo_parent; + _bt_relbuf(rel, buf, BT_WRITE); + _bt_fixtree(rel, blkno, NULL); + goto formres; + } + } + /* + * Ok, we are on the leftmost page, it's write locked + * by us and its btpo_parent points to meta page - time + * for _bt_fixroot(). + */ + buf = _bt_fixroot(rel, buf, true); + _bt_relbuf(rel, buf, BT_WRITE); + goto formres; + } + + /* + * Set up a phony stack entry if we haven't got a real one + */ stack = &fakestack; stack->bts_blkno = lpageop->btpo_parent; stack->bts_offset = InvalidOffsetNumber; @@ -537,6 +585,7 @@ _bt_insertonpg(Relation rel, _bt_wrtbuf(rel, buf); } +formres:; /* by here, the new tuple is inserted at itup_blkno/itup_off */ res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData)); ItemPointerSet(&(res->pointerData), itup_blkno, itup_off); @@ -1414,8 +1463,7 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release) * created with _bt_newroot() - rootbuf, - and buf we've used * for last insert ops - buf. If rootbuf != buf then we have to * create at least one more level. And if "release" is TRUE - * (ie we've already created some levels) then we give up - * oldrootbuf. + * then we give up oldrootbuf. */ if (release) _bt_relbuf(rel, oldrootbuf, BT_WRITE); @@ -1429,6 +1477,12 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release) return(rootbuf); } +static void +_bt_fixtree(Relation rel, BlockNumber blkno, BTStack stack) +{ + elog(ERROR, "bt_fixtree: unimplemented , yet"); +} + /* * _bt_pgaddtup() -- add a tuple to a particular page in the index. * diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index 0f68a066dc..eb9ad9b9dd 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.48 2001/01/26 01:24:31 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.49 2001/01/29 07:28:17 vadim Exp $ * * NOTES * Postgres btree pages look like ordinary relation pages. The opaque @@ -257,6 +257,7 @@ check_parent:; /* handle concurrent fix of root page */ if (rootopaque->btpo_parent == BTREE_METAPAGE) /* unupdated! */ { + elog(NOTICE, "bt_getroot: fixing root page"); newrootbuf = _bt_fixroot(rel, rootbuf, true); LockBuffer(newrootbuf, BUFFER_LOCK_UNLOCK); LockBuffer(newrootbuf, BT_READ); -- 2.40.0