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 {
499499 if (!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 );
504505 goto formres ;
505506 }
@@ -549,10 +550,10 @@ _bt_insertonpg(Relation rel,
549550 elog (ERROR , "_bt_getstackbuf: my bits moved right off the end of the world!"
550551 "\n\tRecreate index %s." , RelationGetRelationName (rel ));
551552 pfree (new_item );
553+ elog (NOTICE , "bt_insertonpg[%s]: parent page unfound - fixing branch" , RelationGetRelationName (rel ));
552554 _bt_fixbranch (rel , bknum , rbknum , stack );
553555 goto formres ;
554556 }
555-
556557 /* Recursively update the parent */
557558 newres = _bt_insertonpg (rel , pbuf , stack -> bts_parent ,
558559 0 , NULL , new_item , stack -> bts_offset );
@@ -1313,6 +1314,11 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
13131314 PageSetLSN (metapg , recptr );
13141315 PageSetSUI (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 }
13171323 END_CRIT_SECTION ();
13181324
@@ -1359,22 +1365,6 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
13591365 rootLSN = PageGetLSN (rootpage );
13601366 rootblk = 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 */
13791369 buf = rootbuf ;
13801370 page = BufferGetPage (buf );
@@ -1401,7 +1391,13 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
14011391 rightpage = BufferGetPage (rightbuf );
14021392 rightopaque = (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+ */
14051401 HOLD_INTERRUPTS ();
14061402 rightopaque -> btpo_parent = rootblk ;
14071403 if (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 );
14461442 pfree (btitem );
14471443 leftbuf = rightbuf ;
14481444 leftpage = rightpage ;
14491445 leftopaque = 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 */
14621458 if (release )
1463- _bt_relbuf (rel , oldrootbuf , BT_WRITE );
1459+ _bt_wrtbuf (rel , oldrootbuf );
14641460
14651461 if (rootbuf != buf )
14661462 {
1467- _bt_relbuf (rel , buf , BT_WRITE );
1463+ _bt_wrtbuf (rel , buf );
14681464 return (_bt_fixroot (rel , rootbuf , true));
14691465 }
14701466
@@ -1483,15 +1479,13 @@ _bt_fixtree(Relation rel, BlockNumber blkno)
14831479 BTPageOpaque opaque ;
14841480 BlockNumber pblkno ;
14851481
1486- elog (ERROR , "bt_fixtree: unimplemented , yet (need to recreate index)" );
1487-
14881482 for ( ; ; )
14891483 {
14901484 buf = _bt_getbuf (rel , blkno , BT_READ );
14911485 page = BufferGetPage (buf );
14921486 opaque = (BTPageOpaque ) PageGetSpecialPointer (page );
14931487 if (! 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 ) );
14951489 pblkno = 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 {
15061502 buf = _bt_getbuf (rel , blkno , BT_WRITE );
15071503 page = BufferGetPage (buf );
@@ -1512,18 +1508,19 @@ _bt_fixtree(Relation rel, BlockNumber blkno)
15121508 _bt_relbuf (rel , buf , BT_WRITE );
15131509 return ;
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 ));
15191515 buf = _bt_fixroot (rel , buf , true);
15201516 _bt_relbuf (rel , buf , BT_WRITE );
15211517 return ;
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 */
15621559 coff [0 ] = P_FIRSTDATAKEY (opaque );
15631560 if (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 ) );
15651562 btitem = (BTItem ) PageGetItem (page , PageGetItemId (page , coff [0 ]));
15661563 cblkno [0 ] = ItemPointerGetBlockNumber (& (btitem -> bti_itup .t_tid ));
15671564 cbuf [0 ] = _bt_getbuf (rel , cblkno [0 ], BT_READ );
15681565 cpage [0 ] = BufferGetPage (cbuf [0 ]);
15691566 copaque [0 ] = (BTPageOpaque ) PageGetSpecialPointer (cpage [0 ]);
15701567 if (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 */
15731570 if (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
15761573 for ( ; ; )
15771574 {
@@ -1597,7 +1594,7 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
15971594 if (coff [i ] == InvalidOffsetNumber )
15981595 continue ;
15991596 if (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 ) );
16011598 break ;
16021599 }
16031600 }
@@ -1629,7 +1626,7 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
16291626
16301627 buf = _bt_getstackbuf (rel , & stack , BT_WRITE );
16311628 if (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
16341631 page = BufferGetPage (buf );
16351632 opaque = (BTPageOpaque ) PageGetSpecialPointer (page );
@@ -1648,7 +1645,7 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
16481645 {
16491646 if (parblk [i ] == parblk [i - 1 ] &&
16501647 coff [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 ) );
16521649 continue ;
16531650 }
16541651 /* Have to check next page ? */
@@ -1662,7 +1659,7 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
16621659 if (coff [i ] != InvalidOffsetNumber ) /* found ! */
16631660 {
16641661 if (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 );
16671664 buf = newbuf ;
16681665 page = newpage ;
@@ -1791,28 +1788,31 @@ _bt_fixbranch(Relation rel, BlockNumber lblkno,
17911788 ItemPointerSet (& (stack .bts_btitem .bti_itup .t_tid ), lblkno , P_HIKEY );
17921789 buf = _bt_getstackbuf (rel , & stack , BT_READ );
17931790 if (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 ) );
17951792 page = BufferGetPage (buf );
17961793 offnum = _bt_getoff (page , rblkno );
17971794
17981795 if (offnum != InvalidOffsetNumber ) /* right pointer found */
17991796 {
18001797 if (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 );
18031800 return ;
18041801 }
18051802
18061803 /* Pointers are on different parent pages - find right one */
18071804 lblkno = 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
18091809 stack .bts_parent = NULL ;
1810- stack .bts_blkno = lblkno ;
1810+ stack .bts_blkno = opaque -> btpo_next ;
18111811 stack .bts_offset = InvalidOffsetNumber ;
18121812 ItemPointerSet (& (stack .bts_btitem .bti_itup .t_tid ), rblkno , P_HIKEY );
18131813 rbuf = _bt_getstackbuf (rel , & stack , BT_READ );
18141814 if (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 ) );
18161816 rblkno = 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 {
18401839 blkno = opaque -> btpo_parent ;
18411840 _bt_relbuf (rel , buf , BT_READ );
@@ -1847,7 +1846,7 @@ _bt_fixbranch(Relation rel, BlockNumber lblkno,
18471846 buf = _bt_getbuf (rel , blkno , BT_WRITE );
18481847 page = BufferGetPage (buf );
18491848 opaque = (BTPageOpaque ) PageGetSpecialPointer (page );
1850- if (opaque -> btpo_parent != BTREE_METAPAGE )
1849+ if (! BTreeInvalidParent ( opaque ) )
18511850 {
18521851 blkno = opaque -> btpo_parent ;
18531852 _bt_relbuf (rel , buf , BT_WRITE );
@@ -1861,6 +1860,7 @@ _bt_fixbranch(Relation rel, BlockNumber lblkno,
18611860 break ;
18621861 }
18631862
1863+ elog (NOTICE , "bt_fixbranch[%s]: fixing upper levels" , RelationGetRelationName (rel ));
18641864 _bt_fixup (rel , buf );
18651865
18661866 return ;
@@ -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 {
18921892 blkno = 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 );
18951896 return ;
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 ));
19101912 buf = _bt_fixroot (rel , buf , true);
19111913 _bt_relbuf (rel , buf , BT_WRITE );
19121914
0 commit comments