8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -494,12 +494,13 @@ _bt_insertonpg(Relation rel,
494
494
* then old root' btpo_parent still points to metapage.
495
495
* We have to fix root page in this case.
496
496
*/
497
- if (lpageop -> btpo_parent == BTREE_METAPAGE )
497
+ if (BTreeInvalidParent ( lpageop ) )
498
498
{
499
499
if (!FixBTree )
500
- elog (ERROR , "bt_insertonpg: no root page found" );
500
+ elog (ERROR , "bt_insertonpg[%s] : no root page found" , RelationGetRelationName ( rel ) );
501
501
_bt_wrtbuf (rel , rbuf );
502
502
_bt_wrtnorelbuf (rel , buf );
503
+ elog (NOTICE , "bt_insertonpg[%s]: root page unfound - fixing upper levels" , RelationGetRelationName (rel ));
503
504
_bt_fixup (rel , buf );
504
505
goto formres ;
505
506
}
@@ -549,10 +550,10 @@ _bt_insertonpg(Relation rel,
549
550
elog (ERROR , "_bt_getstackbuf: my bits moved right off the end of the world!"
550
551
"\n\tRecreate index %s." , RelationGetRelationName (rel ));
551
552
pfree (new_item );
553
+ elog (NOTICE , "bt_insertonpg[%s]: parent page unfound - fixing branch" , RelationGetRelationName (rel ));
552
554
_bt_fixbranch (rel , bknum , rbknum , stack );
553
555
goto formres ;
554
556
}
555
-
556
557
/* Recursively update the parent */
557
558
newres = _bt_insertonpg (rel , pbuf , stack -> bts_parent ,
558
559
0 , NULL , new_item , stack -> bts_offset );
@@ -1313,6 +1314,11 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
1313
1314
PageSetLSN (metapg , recptr );
1314
1315
PageSetSUI (metapg , ThisStartUpID );
1315
1316
1317
+ /* we changed their btpo_parent */
1318
+ PageSetLSN (lpage , recptr );
1319
+ PageSetSUI (lpage , ThisStartUpID );
1320
+ PageSetLSN (rpage , recptr );
1321
+ PageSetSUI (rpage , ThisStartUpID );
1316
1322
}
1317
1323
END_CRIT_SECTION ();
1318
1324
@@ -1359,22 +1365,6 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
1359
1365
rootLSN = PageGetLSN (rootpage );
1360
1366
rootblk = BufferGetBlockNumber (rootbuf );
1361
1367
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
-
1378
1368
/* parent page where to insert pointers */
1379
1369
buf = rootbuf ;
1380
1370
page = BufferGetPage (buf );
@@ -1401,7 +1391,13 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
1401
1391
rightpage = BufferGetPage (rightbuf );
1402
1392
rightopaque = (BTPageOpaque ) PageGetSpecialPointer (rightpage );
1403
1393
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
+ */
1405
1401
HOLD_INTERRUPTS ();
1406
1402
rightopaque -> btpo_parent = rootblk ;
1407
1403
if (XLByteLT (PageGetLSN (rightpage ), rootLSN ))
@@ -1442,15 +1438,15 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
1442
1438
_bt_insertuple (rel , buf , itemsz , btitem , newitemoff );
1443
1439
1444
1440
/* give up left buffer */
1445
- _bt_relbuf (rel , leftbuf , BT_WRITE );
1441
+ _bt_wrtbuf (rel , leftbuf );
1446
1442
pfree (btitem );
1447
1443
leftbuf = rightbuf ;
1448
1444
leftpage = rightpage ;
1449
1445
leftopaque = rightopaque ;
1450
1446
}
1451
1447
1452
1448
/* give up rightmost page buffer */
1453
- _bt_relbuf (rel , leftbuf , BT_WRITE );
1449
+ _bt_wrtbuf (rel , leftbuf );
1454
1450
1455
1451
/*
1456
1452
* 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)
1460
1456
* then we give up oldrootbuf.
1461
1457
*/
1462
1458
if (release )
1463
- _bt_relbuf (rel , oldrootbuf , BT_WRITE );
1459
+ _bt_wrtbuf (rel , oldrootbuf );
1464
1460
1465
1461
if (rootbuf != buf )
1466
1462
{
1467
- _bt_relbuf (rel , buf , BT_WRITE );
1463
+ _bt_wrtbuf (rel , buf );
1468
1464
return (_bt_fixroot (rel , rootbuf , true));
1469
1465
}
1470
1466
@@ -1483,15 +1479,13 @@ _bt_fixtree(Relation rel, BlockNumber blkno)
1483
1479
BTPageOpaque opaque ;
1484
1480
BlockNumber pblkno ;
1485
1481
1486
- elog (ERROR , "bt_fixtree: unimplemented , yet (need to recreate index)" );
1487
-
1488
1482
for ( ; ; )
1489
1483
{
1490
1484
buf = _bt_getbuf (rel , blkno , BT_READ );
1491
1485
page = BufferGetPage (buf );
1492
1486
opaque = (BTPageOpaque ) PageGetSpecialPointer (page );
1493
1487
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 ) );
1495
1489
pblkno = opaque -> btpo_parent ;
1496
1490
1497
1491
/* check/fix entire level */
@@ -1500,8 +1494,10 @@ _bt_fixtree(Relation rel, BlockNumber blkno)
1500
1494
/*
1501
1495
* No pins/locks are held here. Re-read start page if its
1502
1496
* btpo_parent pointed to meta page else go up one level.
1497
+ *
1498
+ * XXX have to catch InvalidBlockNumber at the moment -:(
1503
1499
*/
1504
- if (pblkno == BTREE_METAPAGE )
1500
+ if (pblkno == BTREE_METAPAGE || pblkno == InvalidBlockNumber )
1505
1501
{
1506
1502
buf = _bt_getbuf (rel , blkno , BT_WRITE );
1507
1503
page = BufferGetPage (buf );
@@ -1512,18 +1508,19 @@ _bt_fixtree(Relation rel, BlockNumber blkno)
1512
1508
_bt_relbuf (rel , buf , BT_WRITE );
1513
1509
return ;
1514
1510
}
1515
- pblkno = opaque -> btpo_parent ;
1516
1511
/* Call _bt_fixroot() if there is no upper level */
1517
- if (pblkno == BTREE_METAPAGE )
1512
+ if (BTreeInvalidParent ( opaque ) )
1518
1513
{
1514
+ elog (NOTICE , "bt_fixtree[%s]: fixing root page" , RelationGetRelationName (rel ));
1519
1515
buf = _bt_fixroot (rel , buf , true);
1520
1516
_bt_relbuf (rel , buf , BT_WRITE );
1521
1517
return ;
1522
1518
}
1523
1519
/* Have to go up one level */
1520
+ pblkno = opaque -> btpo_parent ;
1524
1521
_bt_relbuf (rel , buf , BT_WRITE );
1525
- blkno = pblkno ;
1526
1522
}
1523
+ blkno = pblkno ;
1527
1524
}
1528
1525
1529
1526
}
@@ -1561,17 +1558,17 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
1561
1558
/* Initialize first child data */
1562
1559
coff [0 ] = P_FIRSTDATAKEY (opaque );
1563
1560
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 ) );
1565
1562
btitem = (BTItem ) PageGetItem (page , PageGetItemId (page , coff [0 ]));
1566
1563
cblkno [0 ] = ItemPointerGetBlockNumber (& (btitem -> bti_itup .t_tid ));
1567
1564
cbuf [0 ] = _bt_getbuf (rel , cblkno [0 ], BT_READ );
1568
1565
cpage [0 ] = BufferGetPage (cbuf [0 ]);
1569
1566
copaque [0 ] = (BTPageOpaque ) PageGetSpecialPointer (cpage [0 ]);
1570
1567
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 ) );
1572
1569
/* caller should take care and avoid this */
1573
1570
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 ) );
1575
1572
1576
1573
for ( ; ; )
1577
1574
{
@@ -1597,7 +1594,7 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
1597
1594
if (coff [i ] == InvalidOffsetNumber )
1598
1595
continue ;
1599
1596
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 ) );
1601
1598
break ;
1602
1599
}
1603
1600
}
@@ -1629,7 +1626,7 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
1629
1626
1630
1627
buf = _bt_getstackbuf (rel , & stack , BT_WRITE );
1631
1628
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 ) );
1633
1630
1634
1631
page = BufferGetPage (buf );
1635
1632
opaque = (BTPageOpaque ) PageGetSpecialPointer (page );
@@ -1648,7 +1645,7 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
1648
1645
{
1649
1646
if (parblk [i ] == parblk [i - 1 ] &&
1650
1647
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 ) );
1652
1649
continue ;
1653
1650
}
1654
1651
/* Have to check next page ? */
@@ -1662,7 +1659,7 @@ _bt_fixlevel(Relation rel, Buffer buf, BlockNumber limit)
1662
1659
if (coff [i ] != InvalidOffsetNumber ) /* found ! */
1663
1660
{
1664
1661
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 ) );
1666
1663
_bt_relbuf (rel , buf , BT_WRITE );
1667
1664
buf = newbuf ;
1668
1665
page = newpage ;
@@ -1791,28 +1788,31 @@ _bt_fixbranch(Relation rel, BlockNumber lblkno,
1791
1788
ItemPointerSet (& (stack .bts_btitem .bti_itup .t_tid ), lblkno , P_HIKEY );
1792
1789
buf = _bt_getstackbuf (rel , & stack , BT_READ );
1793
1790
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 ) );
1795
1792
page = BufferGetPage (buf );
1796
1793
offnum = _bt_getoff (page , rblkno );
1797
1794
1798
1795
if (offnum != InvalidOffsetNumber ) /* right pointer found */
1799
1796
{
1800
1797
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 ) );
1802
1799
_bt_relbuf (rel , buf , BT_READ );
1803
1800
return ;
1804
1801
}
1805
1802
1806
1803
/* Pointers are on different parent pages - find right one */
1807
1804
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 ));
1808
1808
1809
1809
stack .bts_parent = NULL ;
1810
- stack .bts_blkno = lblkno ;
1810
+ stack .bts_blkno = opaque -> btpo_next ;
1811
1811
stack .bts_offset = InvalidOffsetNumber ;
1812
1812
ItemPointerSet (& (stack .bts_btitem .bti_itup .t_tid ), rblkno , P_HIKEY );
1813
1813
rbuf = _bt_getstackbuf (rel , & stack , BT_READ );
1814
1814
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 ) );
1816
1816
rblkno = BufferGetBlockNumber (rbuf );
1817
1817
_bt_relbuf (rel , rbuf , BT_READ );
1818
1818
@@ -1834,8 +1834,7 @@ _bt_fixbranch(Relation rel, BlockNumber lblkno,
1834
1834
* then we'll use it to continue, else we'll fix/restore upper
1835
1835
* levels entirely.
1836
1836
*/
1837
- opaque = (BTPageOpaque ) PageGetSpecialPointer (page );
1838
- if (opaque -> btpo_parent != BTREE_METAPAGE )
1837
+ if (!BTreeInvalidParent (opaque ))
1839
1838
{
1840
1839
blkno = opaque -> btpo_parent ;
1841
1840
_bt_relbuf (rel , buf , BT_READ );
@@ -1847,7 +1846,7 @@ _bt_fixbranch(Relation rel, BlockNumber lblkno,
1847
1846
buf = _bt_getbuf (rel , blkno , BT_WRITE );
1848
1847
page = BufferGetPage (buf );
1849
1848
opaque = (BTPageOpaque ) PageGetSpecialPointer (page );
1850
- if (opaque -> btpo_parent != BTREE_METAPAGE )
1849
+ if (! BTreeInvalidParent ( opaque ) )
1851
1850
{
1852
1851
blkno = opaque -> btpo_parent ;
1853
1852
_bt_relbuf (rel , buf , BT_WRITE );
@@ -1861,6 +1860,7 @@ _bt_fixbranch(Relation rel, BlockNumber lblkno,
1861
1860
break ;
1862
1861
}
1863
1862
1863
+ elog (NOTICE , "bt_fixbranch[%s]: fixing upper levels" , RelationGetRelationName (rel ));
1864
1864
_bt_fixup (rel , buf );
1865
1865
1866
1866
return ;
@@ -1887,10 +1887,11 @@ _bt_fixup(Relation rel, Buffer buf)
1887
1887
* then it's time for _bt_fixtree() to check upper
1888
1888
* levels and fix them, if required.
1889
1889
*/
1890
- if (opaque -> btpo_parent != BTREE_METAPAGE )
1890
+ if (! BTreeInvalidParent ( opaque ) )
1891
1891
{
1892
1892
blkno = opaque -> btpo_parent ;
1893
1893
_bt_relbuf (rel , buf , BT_WRITE );
1894
+ elog (NOTICE , "bt_fixup[%s]: checking/fixing upper levels" , RelationGetRelationName (rel ));
1894
1895
_bt_fixtree (rel , blkno );
1895
1896
return ;
1896
1897
}
@@ -1907,6 +1908,7 @@ _bt_fixup(Relation rel, Buffer buf)
1907
1908
* by us and its btpo_parent points to meta page - time
1908
1909
* for _bt_fixroot().
1909
1910
*/
1911
+ elog (NOTICE , "bt_fixup[%s]: fixing root page" , RelationGetRelationName (rel ));
1910
1912
buf = _bt_fixroot (rel , buf , true);
1911
1913
_bt_relbuf (rel , buf , BT_WRITE );
1912
1914
0 commit comments