]> granicus.if.org Git - postgresql/commitdiff
Call _bt_fixroot() from _bt_insertonpg.
authorVadim B. Mikheev <vadim4o@yahoo.com>
Mon, 29 Jan 2001 07:28:17 +0000 (07:28 +0000)
committerVadim B. Mikheev <vadim4o@yahoo.com>
Mon, 29 Jan 2001 07:28:17 +0000 (07:28 +0000)
src/backend/access/nbtree/nbtinsert.c
src/backend/access/nbtree/nbtpage.c

index 8f23e16992a5013a5baf2c24980b2ebf8740bb2b..76d2d9ff86921ef80c481db7841a1f33dedf3a2e 100644 (file)
@@ -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.
  *
index 0f68a066dc711fcfd543c0cff40b5f2ea3d5722b..eb9ad9b9dd2da56359f619d7c782dab93ca42bda 100644 (file)
@@ -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);