88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.80 2001/02/02 19:49:15 vadim Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.81 2001/02/07 23:35:33 vadim Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -494,12 +494,13 @@ _bt_insertonpg(Relation rel,
494494 * then old root' btpo_parent still points to metapage.
495495 * We have to fix root page in this case.
496496 */
497- if (lpageop -> btpo_parent == BTREE_METAPAGE )
497+ if (BTreeInvalidParent ( lpageop ) )
498498{
499499if (!FixBTree )
500- elog (ERROR ,"bt_insertonpg: no root page found" );
500+ elog (ERROR ,"bt_insertonpg[%s] : no root page found" , RelationGetRelationName ( rel ) );
501501_bt_wrtbuf (rel ,rbuf );
502502_bt_wrtnorelbuf (rel ,buf );
503+ elog (NOTICE ,"bt_insertonpg[%s]: root page unfound - fixing upper levels" ,RelationGetRelationName (rel ));
503504_bt_fixup (rel ,buf );
504505gotoformres ;
505506}
@@ -549,10 +550,10 @@ _bt_insertonpg(Relation rel,
549550elog (ERROR ,"_bt_getstackbuf: my bits moved right off the end of the world!"
550551"\n\tRecreate index %s." ,RelationGetRelationName (rel ));
551552pfree (new_item );
553+ elog (NOTICE ,"bt_insertonpg[%s]: parent page unfound - fixing branch" ,RelationGetRelationName (rel ));
552554_bt_fixbranch (rel ,bknum ,rbknum ,stack );
553555gotoformres ;
554556}
555-
556557/* Recursively update the parent */
557558newres = _bt_insertonpg (rel ,pbuf ,stack -> bts_parent ,
5585590 ,NULL ,new_item ,stack -> bts_offset );
@@ -1313,6 +1314,11 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
13131314PageSetLSN (metapg ,recptr );
13141315PageSetSUI (metapg ,ThisStartUpID );
13151316
1317+ /* we changed their btpo_parent */
1318+ PageSetLSN (lpage ,recptr );
1319+ PageSetSUI (lpage ,ThisStartUpID );
1320+ PageSetLSN (rpage ,recptr );
1321+ PageSetSUI (rpage ,ThisStartUpID );
13161322}
13171323END_CRIT_SECTION ();
13181324
@@ -1359,22 +1365,6 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
13591365rootLSN = PageGetLSN (rootpage );
13601366rootblk = BufferGetBlockNumber (rootbuf );
13611367
1362- /*
1363- * Update LSN & StartUpID of old root buffer and its neighbor to
1364- * ensure that they will be written on disk after logging new
1365- * root creation. Unfortunately, for the moment (?) we do not
1366- * log this operation and so possibly break our rule to log entire
1367- * page content of first after checkpoint modification.
1368- */
1369- HOLD_INTERRUPTS ();
1370- oldrootopaque -> btpo_parent = rootblk ;
1371- leftopaque -> btpo_parent = rootblk ;
1372- PageSetLSN (oldrootpage ,rootLSN );
1373- PageSetSUI (oldrootpage ,ThisStartUpID );
1374- PageSetLSN (leftpage ,rootLSN );
1375- PageSetSUI (leftpage ,ThisStartUpID );
1376- RESUME_INTERRUPTS ();
1377-
13781368/* parent page where to insert pointers */
13791369buf = rootbuf ;
13801370page = BufferGetPage (buf );
@@ -1401,7 +1391,13 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
14011391rightpage = BufferGetPage (rightbuf );
14021392rightopaque = (BTPageOpaque )PageGetSpecialPointer (rightpage );
14031393
1404- /* Update LSN & StartUpID (see comments above) */
1394+ /*
1395+ * Update LSN & StartUpID of child page buffer to ensure that
1396+ * it will be written on disk after flushing log record for new
1397+ * root creation. Unfortunately, for the moment (?) we do not
1398+ * log this operation and so possibly break our rule to log entire
1399+ * page content on first after checkpoint modification.
1400+ */
14051401HOLD_INTERRUPTS ();
14061402rightopaque -> btpo_parent = rootblk ;
14071403if (XLByteLT (PageGetLSN (rightpage ),rootLSN ))
@@ -1442,15 +1438,15 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
14421438_bt_insertuple (rel ,buf ,itemsz ,btitem ,newitemoff );
14431439
14441440/* give up left buffer */
1445- _bt_relbuf (rel ,leftbuf , BT_WRITE );
1441+ _bt_wrtbuf (rel ,leftbuf );
14461442pfree (btitem );
14471443leftbuf = rightbuf ;
14481444leftpage = rightpage ;
14491445leftopaque = rightopaque ;
14501446}
14511447
14521448/* give up rightmost page buffer */
1453- _bt_relbuf (rel ,leftbuf , BT_WRITE );
1449+ _bt_wrtbuf (rel ,leftbuf );
14541450
14551451/*
14561452 * Here we hold locks on old root buffer, new root buffer we've
@@ -1460,11 +1456,11 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
14601456 * then we give up oldrootbuf.
14611457 */
14621458if (release )
1463- _bt_relbuf (rel ,oldrootbuf , BT_WRITE );
1459+ _bt_wrtbuf (rel ,oldrootbuf );
14641460
14651461if (rootbuf != buf )
14661462{
1467- _bt_relbuf (rel ,buf , BT_WRITE );
1463+ _bt_wrtbuf (rel ,buf );
14681464return (_bt_fixroot (rel ,rootbuf , true));
14691465}
14701466
@@ -1483,15 +1479,13 @@ _bt_fixtree(Relation rel, BlockNumber blkno)
14831479BTPageOpaque opaque ;
14841480BlockNumber pblkno ;
14851481
1486- elog (ERROR ,"bt_fixtree: unimplemented , yet (need to recreate index)" );
1487-
14881482for ( ; ; )
14891483{
14901484buf = _bt_getbuf (rel ,blkno ,BT_READ );
14911485page = BufferGetPage (buf );
14921486opaque = (BTPageOpaque )PageGetSpecialPointer (page );
14931487if (!P_LEFTMOST (opaque )|| P_ISLEAF (opaque ))
1494- elog (ERROR ,"bt_fixtree: invalid start page (need to recreate index)" );
1488+ elog (ERROR ,"bt_fixtree[%s] : invalid start page (need to recreate index)" , RelationGetRelationName ( rel ) );
14951489pblkno = opaque -> btpo_parent ;
14961490
14971491/* check/fix entire level */
@@ -1500,8 +1494,10 @@ _bt_fixtree(Relation rel, BlockNumber blkno)
15001494/*
15011495 * No pins/locks are held here. Re-read start page if its
15021496 * btpo_parent pointed to meta page else go up one level.
1497+ *
1498+ * XXX have to catch InvalidBlockNumber at the moment -:(
15031499 */
1504- if (pblkno == BTREE_METAPAGE )
1500+ if (pblkno == BTREE_METAPAGE || pblkno == InvalidBlockNumber )
15051501{
15061502buf = _bt_getbuf (rel ,blkno ,BT_WRITE );
15071503page = BufferGetPage (buf );
@@ -1512,18 +1508,19 @@ _bt_fixtree(Relation rel, BlockNumber blkno)
15121508_bt_relbuf (rel ,buf ,BT_WRITE );
15131509return ;
15141510}
1515- pblkno = opaque -> btpo_parent ;
15161511/* Call _bt_fixroot() if there is no upper level */
1517- if (pblkno == BTREE_METAPAGE )
1512+ if (BTreeInvalidParent ( opaque ) )
15181513{
1514+ elog (NOTICE ,"bt_fixtree[%s]: fixing root page" ,RelationGetRelationName (rel ));
15191515buf = _bt_fixroot (rel ,buf , true);
15201516_bt_relbuf (rel ,buf ,BT_WRITE );
15211517return ;
15221518}
15231519/* Have to go up one level */
1520+ pblkno = opaque -> btpo_parent ;
15241521_bt_relbuf (rel ,buf ,BT_WRITE );
1525- blkno = pblkno ;
15261522}
1523+ blkno = pblkno ;
15271524}
15281525
15291526}
@@ -1561,17 +1558,17 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
15611558/* Initialize first child data */
15621559coff [0 ]= P_FIRSTDATAKEY (opaque );
15631560if (coff [0 ]> PageGetMaxOffsetNumber (page ))
1564- elog (ERROR ,"bt_fixlevel: invalid maxoff on start page (need to recreate index)" );
1561+ elog (ERROR ,"bt_fixlevel[%s] : invalid maxoff on start page (need to recreate index)" , RelationGetRelationName ( rel ) );
15651562btitem = (BTItem )PageGetItem (page ,PageGetItemId (page ,coff [0 ]));
15661563cblkno [0 ]= ItemPointerGetBlockNumber (& (btitem -> bti_itup .t_tid ));
15671564cbuf [0 ]= _bt_getbuf (rel ,cblkno [0 ],BT_READ );
15681565cpage [0 ]= BufferGetPage (cbuf [0 ]);
15691566copaque [0 ]= (BTPageOpaque )PageGetSpecialPointer (cpage [0 ]);
15701567if (P_LEFTMOST (opaque )&& !P_LEFTMOST (copaque [0 ]))
1571- elog (ERROR ,"bt_fixtlevel: non-leftmost child page of leftmost parent (need to recreate index)" );
1568+ elog (ERROR ,"bt_fixtlevel[%s] : non-leftmost child page of leftmost parent (need to recreate index)" , RelationGetRelationName ( rel ) );
15721569/* caller should take care and avoid this */
15731570if (P_RIGHTMOST (copaque [0 ]))
1574- elog (ERROR ,"bt_fixtlevel: invalid start child (need to recreate index)" );
1571+ elog (ERROR ,"bt_fixtlevel[%s] : invalid start child (need to recreate index)" , RelationGetRelationName ( rel ) );
15751572
15761573for ( ; ; )
15771574{
@@ -1597,7 +1594,7 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
15971594if (coff [i ]== InvalidOffsetNumber )
15981595continue ;
15991596if (coff [cidx ]!= coff [i ]+ 1 )
1600- elog (ERROR ,"bt_fixlevel: invalid item order(1) (need to recreate index)" );
1597+ elog (ERROR ,"bt_fixlevel[%s] : invalid item order(1) (need to recreate index)" , RelationGetRelationName ( rel ) );
16011598break ;
16021599}
16031600}
@@ -1629,7 +1626,7 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
16291626
16301627buf = _bt_getstackbuf (rel ,& stack ,BT_WRITE );
16311628if (buf == InvalidBuffer )
1632- elog (ERROR ,"bt_fixlevel: pointer disappeared (need to recreate index)" );
1629+ elog (ERROR ,"bt_fixlevel[%s] : pointer disappeared (need to recreate index)" , RelationGetRelationName ( rel ) );
16331630
16341631page = BufferGetPage (buf );
16351632opaque = (BTPageOpaque )PageGetSpecialPointer (page );
@@ -1648,7 +1645,7 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
16481645{
16491646if (parblk [i ]== parblk [i - 1 ]&&
16501647coff [i ]!= coff [i - 1 ]+ 1 )
1651- elog (ERROR ,"bt_fixlevel: invalid item order(2) (need to recreate index)" );
1648+ elog (ERROR ,"bt_fixlevel[%s] : invalid item order(2) (need to recreate index)" , RelationGetRelationName ( rel ) );
16521649continue ;
16531650}
16541651/* Have to check next page ? */
@@ -1662,7 +1659,7 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
16621659if (coff [i ]!= InvalidOffsetNumber )/* found ! */
16631660{
16641661if (coff [i ]!= P_FIRSTDATAKEY (newopaque ))
1665- elog (ERROR ,"bt_fixlevel: invalid item order(3) (need to recreate index)" );
1662+ elog (ERROR ,"bt_fixlevel[%s] : invalid item order(3) (need to recreate index)" , RelationGetRelationName ( rel ) );
16661663_bt_relbuf (rel ,buf ,BT_WRITE );
16671664buf = newbuf ;
16681665page = newpage ;
@@ -1791,28 +1788,31 @@ _bt_fixbranch(Relation rel, BlockNumber lblkno,
17911788ItemPointerSet (& (stack .bts_btitem .bti_itup .t_tid ),lblkno ,P_HIKEY );
17921789buf = _bt_getstackbuf (rel ,& stack ,BT_READ );
17931790if (buf == InvalidBuffer )
1794- elog (ERROR ,"bt_fixbranch: left pointer unfound (need to recreate index)" );
1791+ elog (ERROR ,"bt_fixbranch[%s] : left pointer unfound (need to recreate index)" , RelationGetRelationName ( rel ) );
17951792page = BufferGetPage (buf );
17961793offnum = _bt_getoff (page ,rblkno );
17971794
17981795if (offnum != InvalidOffsetNumber )/* right pointer found */
17991796{
18001797if (offnum <=stack .bts_offset )
1801- elog (ERROR ,"bt_fixbranch: invalid item order (need to recreate index)" );
1798+ elog (ERROR ,"bt_fixbranch[%s] : invalid item order (need to recreate index)" , RelationGetRelationName ( rel ) );
18021799_bt_relbuf (rel ,buf ,BT_READ );
18031800return ;
18041801}
18051802
18061803/* Pointers are on different parent pages - find right one */
18071804lblkno = BufferGetBlockNumber (buf );
1805+ opaque = (BTPageOpaque )PageGetSpecialPointer (page );
1806+ if (P_RIGHTMOST (opaque ))
1807+ elog (ERROR ,"bt_fixbranch[%s]: right pointer unfound(1) (need to recreate index)" ,RelationGetRelationName (rel ));
18081808
18091809stack .bts_parent = NULL ;
1810- stack .bts_blkno = lblkno ;
1810+ stack .bts_blkno = opaque -> btpo_next ;
18111811stack .bts_offset = InvalidOffsetNumber ;
18121812ItemPointerSet (& (stack .bts_btitem .bti_itup .t_tid ),rblkno ,P_HIKEY );
18131813rbuf = _bt_getstackbuf (rel ,& stack ,BT_READ );
18141814if (rbuf == InvalidBuffer )
1815- elog (ERROR ,"bt_fixbranch: right pointer unfound (need to recreate index)" );
1815+ elog (ERROR ,"bt_fixbranch[%s] : right pointer unfound(2) (need to recreate index)" , RelationGetRelationName ( rel ) );
18161816rblkno = BufferGetBlockNumber (rbuf );
18171817_bt_relbuf (rel ,rbuf ,BT_READ );
18181818
@@ -1834,8 +1834,7 @@ _bt_fixbranch(Relation rel, BlockNumber lblkno,
18341834 * then we'll use it to continue, else we'll fix/restore upper
18351835 * levels entirely.
18361836 */
1837- opaque = (BTPageOpaque )PageGetSpecialPointer (page );
1838- if (opaque -> btpo_parent != BTREE_METAPAGE )
1837+ if (!BTreeInvalidParent (opaque ))
18391838{
18401839blkno = opaque -> btpo_parent ;
18411840_bt_relbuf (rel ,buf ,BT_READ );
@@ -1847,7 +1846,7 @@ _bt_fixbranch(Relation rel, BlockNumber lblkno,
18471846buf = _bt_getbuf (rel ,blkno ,BT_WRITE );
18481847page = BufferGetPage (buf );
18491848opaque = (BTPageOpaque )PageGetSpecialPointer (page );
1850- if (opaque -> btpo_parent != BTREE_METAPAGE )
1849+ if (! BTreeInvalidParent ( opaque ) )
18511850{
18521851blkno = opaque -> btpo_parent ;
18531852_bt_relbuf (rel ,buf ,BT_WRITE );
@@ -1861,6 +1860,7 @@ _bt_fixbranch(Relation rel, BlockNumber lblkno,
18611860break ;
18621861}
18631862
1863+ elog (NOTICE ,"bt_fixbranch[%s]: fixing upper levels" ,RelationGetRelationName (rel ));
18641864_bt_fixup (rel ,buf );
18651865
18661866return ;
@@ -1887,10 +1887,11 @@ _bt_fixup(Relation rel, Buffer buf)
18871887 * then it's time for _bt_fixtree() to check upper
18881888 * levels and fix them, if required.
18891889 */
1890- if (opaque -> btpo_parent != BTREE_METAPAGE )
1890+ if (! BTreeInvalidParent ( opaque ) )
18911891{
18921892blkno = opaque -> btpo_parent ;
18931893_bt_relbuf (rel ,buf ,BT_WRITE );
1894+ elog (NOTICE ,"bt_fixup[%s]: checking/fixing upper levels" ,RelationGetRelationName (rel ));
18941895_bt_fixtree (rel ,blkno );
18951896return ;
18961897}
@@ -1907,6 +1908,7 @@ _bt_fixup(Relation rel, Buffer buf)
19071908 * by us and its btpo_parent points to meta page - time
19081909 * for _bt_fixroot().
19091910 */
1911+ elog (NOTICE ,"bt_fixup[%s]: fixing root page" ,RelationGetRelationName (rel ));
19101912buf = _bt_fixroot (rel ,buf , true);
19111913_bt_relbuf (rel ,buf ,BT_WRITE );
19121914