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

Commit7e30c18

Browse files
committed
Retain original physical order of tuples in redo of b-tree splits.
It makes no difference to the system, but minimizing the differencesbetween a master and standby makes debugging simpler.
1 parent7d98054 commit7e30c18

File tree

1 file changed

+70
-46
lines changed

1 file changed

+70
-46
lines changed

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

Lines changed: 70 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -27,28 +27,42 @@
2727
* had been its upper part (pd_upper to pd_special). We assume that the
2828
* tuples had been added to the page in item-number order, and therefore
2929
* the one with highest item number appears first (lowest on the page).
30-
*
31-
* NOTE: the way this routine is coded, the rebuilt page will have the items
32-
* in correct itemno sequence, but physically the opposite order from the
33-
* original, because we insert them in the opposite of itemno order. This
34-
* does not matter in any current btree code, but it's something to keep an
35-
* eye on.Is it worth changing just on general principles? See also the
36-
* notes in btree_xlog_split().
3730
*/
3831
staticvoid
3932
_bt_restore_page(Pagepage,char*from,intlen)
4033
{
4134
IndexTupleDataitupdata;
4235
Sizeitemsz;
4336
char*end=from+len;
37+
Itemitems[MaxIndexTuplesPerPage];
38+
uint16itemsizes[MaxIndexTuplesPerPage];
39+
inti;
40+
intnitems;
4441

45-
for (;from<end;)
42+
/*
43+
* To get the items back in the original order, we add them to the page
44+
* in reverse. To figure out where one tuple ends and another begins,
45+
* we have to scan them in forward order first.
46+
*/
47+
i=0;
48+
while (from<end)
4649
{
4750
/* Need to copy tuple header due to alignment considerations */
4851
memcpy(&itupdata,from,sizeof(IndexTupleData));
4952
itemsz=IndexTupleDSize(itupdata);
5053
itemsz=MAXALIGN(itemsz);
51-
if (PageAddItem(page, (Item)from,itemsz,FirstOffsetNumber,
54+
55+
items[i]= (Item)from;
56+
itemsizes[i]=itemsz;
57+
i++;
58+
59+
from+=itemsz;
60+
}
61+
nitems=i;
62+
63+
for (i=nitems-1;i >=0;i--)
64+
{
65+
if (PageAddItem(page,items[i],itemsizes[i],nitems-i,
5266
false, false)==InvalidOffsetNumber)
5367
elog(PANIC,"_bt_restore_page: cannot add item to page");
5468
from+=itemsz;
@@ -332,56 +346,66 @@ btree_xlog_split(bool onleft, bool isroot,
332346
if (BufferIsValid(lbuf))
333347
{
334348
/*
335-
* Note that this code ensures that the items remaining on the
336-
* left page are in the correct item number order, but it does not
337-
* reproduce the physical order they would have had. Is this
338-
* worth changing?See also _bt_restore_page().
349+
* To retain the same physical order of the tuples that they had,
350+
* we initialize a temporary empty page for the left page and add
351+
* all the items to that in item number order. This mirrors how
352+
* _bt_split() works. It's not strictly required to retain the
353+
* same physical order, as long as the items are in the correct
354+
* item number order, but it helps debugging. See also
355+
* _bt_restore_page(), which does the same for the right page.
339356
*/
340357
Pagelpage= (Page)BufferGetPage(lbuf);
341358
BTPageOpaquelopaque= (BTPageOpaque)PageGetSpecialPointer(lpage);
342359

343360
if (lsn>PageGetLSN(lpage))
344361
{
345362
OffsetNumberoff;
346-
OffsetNumbermaxoff=PageGetMaxOffsetNumber(lpage);
347-
OffsetNumberdeletable[MaxOffsetNumber];
348-
intndeletable=0;
349-
350-
/*
351-
* Remove the items from the left page that were copied to the
352-
* right page.Also remove the old high key, if any. (We must
353-
* remove everything before trying to insert any items, else
354-
* we risk not having enough space.)
355-
*/
356-
if (!P_RIGHTMOST(lopaque))
357-
{
358-
deletable[ndeletable++]=P_HIKEY;
363+
Pagenewlpage;
364+
OffsetNumberleftoff;
359365

360-
/*
361-
* newitemoff is given to us relative to the original
362-
* page's item numbering, so adjust it for this deletion.
363-
*/
364-
newitemoff--;
366+
newlpage=PageGetTempPageCopySpecial(lpage);
367+
368+
/* Set high key */
369+
leftoff=P_HIKEY;
370+
if (PageAddItem(newlpage,left_hikey,left_hikeysz,
371+
P_HIKEY, false, false)==InvalidOffsetNumber)
372+
elog(PANIC,"failed to add high key to left page after split");
373+
leftoff=OffsetNumberNext(leftoff);
374+
375+
for (off=P_FIRSTDATAKEY(lopaque);off<xlrec->firstright;off++)
376+
{
377+
ItemIditemid;
378+
Sizeitemsz;
379+
Itemitem;
380+
381+
/* add the new item if it was inserted on left page */
382+
if (onleft&&off==newitemoff)
383+
{
384+
if (PageAddItem(newlpage,newitem,newitemsz,leftoff,
385+
false, false)==InvalidOffsetNumber)
386+
elog(ERROR,"failed to add new item to left page after split");
387+
leftoff=OffsetNumberNext(leftoff);
388+
}
389+
390+
itemid=PageGetItemId(lpage,off);
391+
itemsz=ItemIdGetLength(itemid);
392+
item=PageGetItem(lpage,itemid);
393+
if (PageAddItem(newlpage,item,itemsz,leftoff,
394+
false, false)==InvalidOffsetNumber)
395+
elog(ERROR,"failed to add old item to left page after split");
396+
leftoff=OffsetNumberNext(leftoff);
365397
}
366-
for (off=xlrec->firstright;off <=maxoff;off++)
367-
deletable[ndeletable++]=off;
368-
if (ndeletable>0)
369-
PageIndexMultiDelete(lpage,deletable,ndeletable);
370-
371-
/*
372-
* Add the new item if it was inserted on left page.
373-
*/
374-
if (onleft)
398+
399+
/* cope with possibility that newitem goes at the end */
400+
if (onleft&&off==newitemoff)
375401
{
376-
if (PageAddItem(lpage,newitem,newitemsz,newitemoff,
402+
if (PageAddItem(newlpage,newitem,newitemsz,leftoff,
377403
false, false)==InvalidOffsetNumber)
378-
elog(PANIC,"failed to add new item to left page after split");
404+
elog(ERROR,"failed to add new item to left page after split");
405+
leftoff=OffsetNumberNext(leftoff);
379406
}
380407

381-
/* Set high key */
382-
if (PageAddItem(lpage,left_hikey,left_hikeysz,
383-
P_HIKEY, false, false)==InvalidOffsetNumber)
384-
elog(PANIC,"failed to add high key to left page after split");
408+
PageRestoreTempPage(newlpage,lpage);
385409

386410
/* Fix opaque fields */
387411
lopaque->btpo_flags=BTP_INCOMPLETE_SPLIT;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp