Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdca0762

Browse files
committed
Couple additional functions to fix tree at runtime.
Need in one more function to handle "my bits moved..."case. FixBTree is still FALSE.
1 parented7910e commitdca0762

File tree

1 file changed

+324
-7
lines changed

1 file changed

+324
-7
lines changed

‎src/backend/access/nbtree/nbtinsert.c

Lines changed: 324 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.78 2001/01/29 07:28:16 vadim Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.79 2001/01/31 01:08:36 vadim Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -37,7 +37,9 @@ typedef struct
3737
externboolFixBTree;
3838

3939
Buffer_bt_fixroot(Relationrel,Bufferoldrootbuf,boolrelease);
40-
staticvoid_bt_fixtree(Relationrel,BlockNumberblkno,BTStackstack);
40+
staticvoid_bt_fixtree(Relationrel,BlockNumberblkno);
41+
staticBlockNumber_bt_fixlevel(Relationrel,Bufferbuf,BlockNumberlimit);
42+
staticOffsetNumber_bt_getoff(Pagepage,BlockNumberblkno);
4143

4244
staticBuffer_bt_newroot(Relationrel,Bufferlbuf,Bufferrbuf);
4345

@@ -512,7 +514,7 @@ _bt_insertonpg(Relation rel,
512514
{
513515
blkno=lpageop->btpo_parent;
514516
_bt_relbuf(rel,buf,BT_WRITE);
515-
_bt_fixtree(rel,blkno,NULL);
517+
_bt_fixtree(rel,blkno);
516518
gotoformres;
517519
}
518520
}
@@ -561,6 +563,10 @@ _bt_insertonpg(Relation rel,
561563

562564
pbuf=_bt_getstackbuf(rel,stack);
563565

566+
if (pbuf==InvalidBuffer)
567+
elog(ERROR,"_bt_getstackbuf: my bits moved right off the end of the world!"
568+
"\n\tRecreate index %s.",RelationGetRelationName(rel));
569+
564570
/* Now we can write and unlock the children */
565571
_bt_wrtbuf(rel,rbuf);
566572
_bt_wrtbuf(rel,buf);
@@ -1172,8 +1178,10 @@ _bt_getstackbuf(Relation rel, BTStack stack)
11721178
}
11731179
/* by here, the item we're looking for moved right at least one page */
11741180
if (P_RIGHTMOST(opaque))
1175-
elog(FATAL,"_bt_getstackbuf: my bits moved right off the end of the world!"
1176-
"\n\tRecreate index %s.",RelationGetRelationName(rel));
1181+
{
1182+
_bt_relbuf(rel,buf,BT_WRITE);
1183+
return(InvalidBuffer);
1184+
}
11771185

11781186
blkno=opaque->btpo_next;
11791187
_bt_relbuf(rel,buf,BT_WRITE);
@@ -1450,6 +1458,7 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
14501458

14511459
/* give up left buffer */
14521460
_bt_relbuf(rel,leftbuf,BT_WRITE);
1461+
pfree(btitem);
14531462
leftbuf=rightbuf;
14541463
leftpage=rightpage;
14551464
leftopaque=rightopaque;
@@ -1477,10 +1486,318 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
14771486
return(rootbuf);
14781487
}
14791488

1489+
/*
1490+
* Using blkno of leftmost page on a level inside tree this func
1491+
* checks/fixes tree from this level up to the root page.
1492+
*/
14801493
staticvoid
1481-
_bt_fixtree(Relationrel,BlockNumberblkno,BTStackstack)
1494+
_bt_fixtree(Relationrel,BlockNumberblkno)
1495+
{
1496+
Bufferbuf;
1497+
Pagepage;
1498+
BTPageOpaqueopaque;
1499+
BlockNumberpblkno;
1500+
1501+
elog(ERROR,"bt_fixtree: unimplemented , yet (need to recreate index)");
1502+
1503+
for ( ; ; )
1504+
{
1505+
buf=_bt_getbuf(rel,blkno,BT_READ);
1506+
page=BufferGetPage(buf);
1507+
opaque= (BTPageOpaque)PageGetSpecialPointer(page);
1508+
if (!P_LEFTMOST(opaque)||P_ISLEAF(opaque))
1509+
elog(ERROR,"bt_fixtree: invalid start page (need to recreate index)");
1510+
pblkno=opaque->btpo_parent;
1511+
1512+
/* check/fix entire level */
1513+
_bt_fixlevel(rel,buf,InvalidBlockNumber);
1514+
1515+
/*
1516+
* No pins/locks are held here. Re-read start page if its
1517+
* btpo_parent pointed to meta page else go up one level.
1518+
*/
1519+
if (pblkno==BTREE_METAPAGE)
1520+
{
1521+
buf=_bt_getbuf(rel,blkno,BT_WRITE);
1522+
page=BufferGetPage(buf);
1523+
opaque= (BTPageOpaque)PageGetSpecialPointer(page);
1524+
if (P_ISROOT(opaque))
1525+
{
1526+
/* Tree is Ok now */
1527+
_bt_relbuf(rel,buf,BT_WRITE);
1528+
return;
1529+
}
1530+
pblkno=opaque->btpo_parent;
1531+
/* Call _bt_fixroot() if there is no upper level */
1532+
if (pblkno==BTREE_METAPAGE)
1533+
{
1534+
buf=_bt_fixroot(rel,buf, true);
1535+
_bt_relbuf(rel,buf,BT_WRITE);
1536+
return;
1537+
}
1538+
/* Have to go up one level */
1539+
_bt_relbuf(rel,buf,BT_WRITE);
1540+
blkno=pblkno;
1541+
}
1542+
}
1543+
1544+
}
1545+
1546+
/*
1547+
* Check/fix level starting from page in buffer buf up to block
1548+
* limit on *child* level (or till rightmost child page if limit
1549+
* is InvalidBlockNumber). Start buffer must be read locked.
1550+
* No pins/locks are held on exit. Returns block number of last
1551+
* visited/pointing-to-limit page on *check/fix* level.
1552+
*/
1553+
staticBlockNumber
1554+
_bt_fixlevel(Relationrel,Bufferbuf,BlockNumberlimit)
1555+
{
1556+
BlockNumberblkno=BufferGetBlockNumber(buf);
1557+
BlockNumberpblkno=blkno;
1558+
Pagepage;
1559+
BTPageOpaqueopaque;
1560+
BlockNumbercblkno[3];
1561+
OffsetNumbercoff[3];
1562+
Buffercbuf[3];
1563+
Pagecpage[3];
1564+
BTPageOpaquecopaque[3];
1565+
BTItembtitem;
1566+
intcidx,i;
1567+
boolgoodbye= false;
1568+
chartbuf[BLCKSZ];
1569+
1570+
page=BufferGetPage(buf);
1571+
/* copy page to temp storage */
1572+
memmove(tbuf,page,PageGetPageSize(page));
1573+
_bt_relbuf(rel,buf,BT_READ);
1574+
1575+
page= (Page)tbuf;
1576+
opaque= (BTPageOpaque)PageGetSpecialPointer(page);
1577+
1578+
/* Initialize first child data */
1579+
coff[0]=P_FIRSTDATAKEY(opaque);
1580+
if (coff[0]>PageGetMaxOffsetNumber(page))
1581+
elog(ERROR,"bt_fixlevel: invalid maxoff on start page (need to recreate index)");
1582+
btitem= (BTItem)PageGetItem(page,PageGetItemId(page,coff[0]));
1583+
cblkno[0]=ItemPointerGetBlockNumber(&(btitem->bti_itup.t_tid));
1584+
cbuf[0]=_bt_getbuf(rel,cblkno[0],BT_READ);
1585+
cpage[0]=BufferGetPage(cbuf[0]);
1586+
copaque[0]= (BTPageOpaque)PageGetSpecialPointer(cpage[0]);
1587+
if (P_LEFTMOST(opaque)&& !P_LEFTMOST(copaque[0]))
1588+
elog(ERROR,"bt_fixtlevel: non-leftmost child page of leftmost parent (need to recreate index)");
1589+
/* caller should take care and avoid this */
1590+
if (P_RIGHTMOST(copaque[0]))
1591+
elog(ERROR,"bt_fixtlevel: invalid start child (need to recreate index)");
1592+
1593+
for ( ; ; )
1594+
{
1595+
/*
1596+
* Read up to 2 more child pages and look for pointers
1597+
* to them in *saved* parent page
1598+
*/
1599+
coff[1]=coff[2]=InvalidOffsetNumber;
1600+
for (cidx=0;cidx<2; )
1601+
{
1602+
cidx++;
1603+
cblkno[cidx]= (copaque[cidx-1])->btpo_next;
1604+
cbuf[cidx]=_bt_getbuf(rel,cblkno[cidx],BT_READ);
1605+
cpage[cidx]=BufferGetPage(cbuf[cidx]);
1606+
copaque[cidx]= (BTPageOpaque)PageGetSpecialPointer(cpage[cidx]);
1607+
coff[cidx]=_bt_getoff(page,cblkno[cidx]);
1608+
1609+
/* sanity check */
1610+
if (coff[cidx]!=InvalidOffsetNumber)
1611+
{
1612+
for (i=cidx-1;i >=0;i--)
1613+
{
1614+
if (coff[i]==InvalidOffsetNumber)
1615+
continue;
1616+
if (coff[cidx]!=coff[i]+1)
1617+
elog(ERROR,"bt_fixlevel: invalid item order(1) (need to recreate index)");
1618+
break;
1619+
}
1620+
}
1621+
1622+
if (P_RIGHTMOST(copaque[cidx]))
1623+
break;
1624+
}
1625+
1626+
/*
1627+
* Read parent page and insert missed pointers.
1628+
*/
1629+
if (coff[1]==InvalidOffsetNumber||
1630+
(cidx==2&&coff[2]==InvalidOffsetNumber))
1631+
{
1632+
Buffernewbuf;
1633+
Pagenewpage;
1634+
BTPageOpaquenewopaque;
1635+
BTItemritem;
1636+
Sizeitemsz;
1637+
OffsetNumbernewitemoff;
1638+
BlockNumberparblk[3];
1639+
BTStackDatastack;
1640+
1641+
stack.bts_parent=NULL;
1642+
stack.bts_blkno=pblkno;
1643+
stack.bts_offset=InvalidOffsetNumber;
1644+
ItemPointerSet(&(stack.bts_btitem.bti_itup.t_tid),
1645+
cblkno[0],P_HIKEY);
1646+
1647+
buf=_bt_getstackbuf(rel,&stack);
1648+
if (buf==InvalidBuffer)
1649+
elog(ERROR,"bt_fixlevel: pointer disappeared (need to recreate index)");
1650+
1651+
page=BufferGetPage(buf);
1652+
opaque= (BTPageOpaque)PageGetSpecialPointer(page);
1653+
coff[0]=stack.bts_offset;
1654+
pblkno=BufferGetBlockNumber(buf);
1655+
parblk[0]=pblkno;
1656+
if (cblkno[0]==limit)
1657+
blkno=pblkno;/* where we have seen pointer to limit */
1658+
1659+
/* Check/insert missed pointers */
1660+
for (i=1;i <=cidx;i++)
1661+
{
1662+
coff[i]=_bt_getoff(page,cblkno[i]);
1663+
1664+
/* sanity check */
1665+
parblk[i]=BufferGetBlockNumber(buf);
1666+
if (coff[i]!=InvalidOffsetNumber)
1667+
{
1668+
if (parblk[i]==parblk[i-1]&&
1669+
coff[i]!=coff[i-1]+1)
1670+
elog(ERROR,"bt_fixlevel: invalid item order(2) (need to recreate index)");
1671+
if (cblkno[i]==limit)
1672+
blkno=parblk[i];
1673+
continue;
1674+
}
1675+
/* Have to check next page ? */
1676+
if ((!P_RIGHTMOST(opaque))&&
1677+
coff[i-1]==PageGetMaxOffsetNumber(page))/* yes */
1678+
{
1679+
newbuf=_bt_getbuf(rel,opaque->btpo_next,BT_WRITE);
1680+
newpage=BufferGetPage(newbuf);
1681+
newopaque= (BTPageOpaque)PageGetSpecialPointer(newpage);
1682+
coff[i]=_bt_getoff(newpage,cblkno[i]);
1683+
if (coff[i]!=InvalidOffsetNumber)/* found ! */
1684+
{
1685+
if (coff[i]!=P_FIRSTDATAKEY(newopaque))
1686+
elog(ERROR,"bt_fixlevel: invalid item order(3) (need to recreate index)");
1687+
_bt_relbuf(rel,buf,BT_WRITE);
1688+
buf=newbuf;
1689+
page=newpage;
1690+
opaque=newopaque;
1691+
pblkno=BufferGetBlockNumber(buf);
1692+
parblk[i]=pblkno;
1693+
if (cblkno[i]==limit)
1694+
blkno=pblkno;
1695+
continue;
1696+
}
1697+
/* unfound - need to insert on current page */
1698+
_bt_relbuf(rel,newbuf,BT_WRITE);
1699+
}
1700+
/* insert pointer */
1701+
ritem= (BTItem)PageGetItem(cpage[i-1],
1702+
PageGetItemId(cpage[i-1],P_HIKEY));
1703+
btitem=_bt_formitem(&(ritem->bti_itup));
1704+
ItemPointerSet(&(btitem->bti_itup.t_tid),cblkno[i],P_HIKEY);
1705+
itemsz=IndexTupleDSize(btitem->bti_itup)
1706+
+ (sizeof(BTItemData)-sizeof(IndexTupleData));
1707+
itemsz=MAXALIGN(itemsz);
1708+
1709+
newitemoff=coff[i-1]+1;
1710+
1711+
if (PageGetFreeSpace(page)<itemsz)
1712+
{
1713+
OffsetNumberfirstright;
1714+
OffsetNumberitup_off;
1715+
BlockNumberitup_blkno;
1716+
boolnewitemonleft;
1717+
1718+
firstright=_bt_findsplitloc(rel,page,
1719+
newitemoff,itemsz,&newitemonleft);
1720+
newbuf=_bt_split(rel,buf,firstright,
1721+
newitemoff,itemsz,btitem,newitemonleft,
1722+
&itup_off,&itup_blkno);
1723+
/* what buffer we need in ? */
1724+
if (newitemonleft)
1725+
_bt_relbuf(rel,newbuf,BT_WRITE);
1726+
else
1727+
{
1728+
_bt_relbuf(rel,buf,BT_WRITE);
1729+
buf=newbuf;
1730+
page=BufferGetPage(buf);
1731+
opaque= (BTPageOpaque)PageGetSpecialPointer(page);
1732+
}
1733+
pblkno=BufferGetBlockNumber(buf);
1734+
coff[i]=itup_off;
1735+
}
1736+
else
1737+
{
1738+
_bt_insertuple(rel,buf,itemsz,btitem,newitemoff);
1739+
coff[i]=newitemoff;
1740+
}
1741+
1742+
pfree(btitem);
1743+
parblk[i]=pblkno;
1744+
if (cblkno[i]==limit)
1745+
blkno=pblkno;
1746+
}
1747+
1748+
/* copy page with pointer to cblkno[cidx] to temp storage */
1749+
memmove(tbuf,page,PageGetPageSize(page));
1750+
_bt_relbuf(rel,buf,BT_WRITE);
1751+
page= (Page)tbuf;
1752+
opaque= (BTPageOpaque)PageGetSpecialPointer(page);
1753+
if (limit==InvalidBlockNumber)
1754+
blkno=pblkno;/* last visited page */
1755+
}
1756+
1757+
/* Continue if current check/fix level page is rightmost */
1758+
if (P_RIGHTMOST(opaque))
1759+
goodbye= false;
1760+
1761+
/* Pointers to child pages are Ok - right end of child level ? */
1762+
_bt_relbuf(rel,cbuf[0],BT_READ);
1763+
_bt_relbuf(rel,cbuf[1],BT_READ);
1764+
if (cidx==1||
1765+
(cidx==2&& (P_RIGHTMOST(copaque[2])||goodbye)))
1766+
{
1767+
if (cidx==2)
1768+
_bt_relbuf(rel,cbuf[2],BT_READ);
1769+
return(blkno);
1770+
}
1771+
if (cblkno[0]==limit||cblkno[1]==limit)
1772+
goodbye= true;
1773+
cblkno[0]=cblkno[2];
1774+
cbuf[0]=cbuf[2];
1775+
cpage[0]=cpage[2];
1776+
copaque[0]=copaque[2];
1777+
coff[0]=coff[2];
1778+
}
1779+
}
1780+
1781+
staticOffsetNumber
1782+
_bt_getoff(Pagepage,BlockNumberblkno)
14821783
{
1483-
elog(ERROR,"bt_fixtree: unimplemented , yet");
1784+
BTPageOpaqueopaque= (BTPageOpaque)PageGetSpecialPointer(page);
1785+
OffsetNumbermaxoff=PageGetMaxOffsetNumber(page);
1786+
OffsetNumberoffnum=P_FIRSTDATAKEY(opaque);
1787+
BlockNumbercurblkno;
1788+
ItemIditemid;
1789+
BTItemitem;
1790+
1791+
for ( ;offnum <=maxoff;offnum++)
1792+
{
1793+
itemid=PageGetItemId(page,offnum);
1794+
item= (BTItem)PageGetItem(page,itemid);
1795+
curblkno=ItemPointerGetBlockNumber(&(item->bti_itup.t_tid));
1796+
if (curblkno==blkno)
1797+
return(offnum);
1798+
}
1799+
1800+
return(InvalidOffsetNumber);
14841801
}
14851802

14861803
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp