Commit 598a1272 authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

Call _bt_fixroot() from _bt_insertonpg.

parent 72401a44
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 ...@@ -34,7 +34,10 @@ typedef struct
int best_delta; /* best size delta so far */ int best_delta; /* best size delta so far */
} FindSplitData; } FindSplitData;
extern bool FixBTree;
Buffer _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release); 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); static Buffer _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf);
...@@ -477,10 +480,55 @@ _bt_insertonpg(Relation rel, ...@@ -477,10 +480,55 @@ _bt_insertonpg(Relation rel,
BTItem ritem; BTItem ritem;
Buffer pbuf; 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) if (stack == (BTStack) NULL)
{ {
elog(DEBUG, "btree: concurrent ROOT page split"); 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 = &fakestack;
stack->bts_blkno = lpageop->btpo_parent; stack->bts_blkno = lpageop->btpo_parent;
stack->bts_offset = InvalidOffsetNumber; stack->bts_offset = InvalidOffsetNumber;
...@@ -537,6 +585,7 @@ _bt_insertonpg(Relation rel, ...@@ -537,6 +585,7 @@ _bt_insertonpg(Relation rel,
_bt_wrtbuf(rel, buf); _bt_wrtbuf(rel, buf);
} }
formres:;
/* by here, the new tuple is inserted at itup_blkno/itup_off */ /* by here, the new tuple is inserted at itup_blkno/itup_off */
res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData)); res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
ItemPointerSet(&(res->pointerData), itup_blkno, itup_off); ItemPointerSet(&(res->pointerData), itup_blkno, itup_off);
...@@ -1414,8 +1463,7 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release) ...@@ -1414,8 +1463,7 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
* created with _bt_newroot() - rootbuf, - and buf we've used * created with _bt_newroot() - rootbuf, - and buf we've used
* for last insert ops - buf. If rootbuf != buf then we have to * for last insert ops - buf. If rootbuf != buf then we have to
* create at least one more level. And if "release" is TRUE * create at least one more level. And if "release" is TRUE
* (ie we've already created some levels) then we give up * then we give up oldrootbuf.
* oldrootbuf.
*/ */
if (release) if (release)
_bt_relbuf(rel, oldrootbuf, BT_WRITE); _bt_relbuf(rel, oldrootbuf, BT_WRITE);
...@@ -1429,6 +1477,12 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release) ...@@ -1429,6 +1477,12 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
return(rootbuf); 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. * _bt_pgaddtup() -- add a tuple to a particular page in the index.
* *
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* Postgres btree pages look like ordinary relation pages. The opaque * Postgres btree pages look like ordinary relation pages. The opaque
...@@ -257,6 +257,7 @@ check_parent:; ...@@ -257,6 +257,7 @@ check_parent:;
/* handle concurrent fix of root page */ /* handle concurrent fix of root page */
if (rootopaque->btpo_parent == BTREE_METAPAGE) /* unupdated! */ if (rootopaque->btpo_parent == BTREE_METAPAGE) /* unupdated! */
{ {
elog(NOTICE, "bt_getroot: fixing root page");
newrootbuf = _bt_fixroot(rel, rootbuf, true); newrootbuf = _bt_fixroot(rel, rootbuf, true);
LockBuffer(newrootbuf, BUFFER_LOCK_UNLOCK); LockBuffer(newrootbuf, BUFFER_LOCK_UNLOCK);
LockBuffer(newrootbuf, BT_READ); LockBuffer(newrootbuf, BT_READ);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment