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

Commitbc175eb

Browse files
committed
Fix two ancient bugs in GiST code to re-find a parent after page split:
First, when following a right-link, we incorrectly marked the current pageas the parent of the right sibling. In reality, the parent of the right pageis the same as the parent of the current page (or some page to the right ofit, gistFindCorrectParent() will sort that out).Secondly, when we follow a right-link, we must prepend, not append, the rightpage to our list of pages to visit. That's because we assume that once wehit a leaf page in the list, all the rest are leaf pages too, and give up.To hit these bugs, you need concurrent actions and several unlucky accidents.Another backend must split the root page, while you're in process ofsplitting a lower-level page. Furthermore, while you scan the internal nodesto re-find the parent, another backend needs to again split some more internalpages. Even then, the bugs don't necessarily manifest as user-visible errorsor index corruption.While we're at it, make the error reporting a bit better if gistFindPath()fails to re-find the parent. It used to be an assertion, but an elog() seemsmore appropriate.Backpatch to all supported branches.
1 parent1be9cdf commitbc175eb

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

‎src/backend/access/gist/gist.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -884,9 +884,12 @@ gistFindPath(Relation r, BlockNumber child)
884884

885885
if (GistPageIsLeaf(page))
886886
{
887-
/* we can safety go away, follows only leaf pages */
887+
/*
888+
* Because we scan the index top-down, all the rest of the pages
889+
* in the queue must be leaf pages as well.
890+
*/
888891
UnlockReleaseBuffer(buffer);
889-
returnNULL;
892+
break;
890893
}
891894

892895
top->lsn=PageGetLSN(page);
@@ -901,14 +904,25 @@ gistFindPath(Relation r, BlockNumber child)
901904
if (top->parent&&XLByteLT(top->parent->lsn,GistPageGetOpaque(page)->nsn)&&
902905
GistPageGetOpaque(page)->rightlink!=InvalidBlockNumber/* sanity check */ )
903906
{
904-
/* page splited while we thinking of... */
907+
/*
908+
* Page was split while we looked elsewhere. We didn't see the
909+
* downlink to the right page when we scanned the parent, so
910+
* add it to the queue now.
911+
*
912+
* Put the right page ahead of the queue, so that we visit it
913+
* next. That's important, because if this is the lowest internal
914+
* level, just above leaves, we might already have queued up some
915+
* leaf pages, and we assume that there can't be any non-leaf
916+
* pages behind leaf pages.
917+
*/
905918
ptr= (GISTInsertStack*)palloc0(sizeof(GISTInsertStack));
906919
ptr->blkno=GistPageGetOpaque(page)->rightlink;
907920
ptr->childoffnum=InvalidOffsetNumber;
908-
ptr->parent=top;
909-
ptr->next=NULL;
910-
tail->next=ptr;
911-
tail=ptr;
921+
ptr->parent=top->parent;
922+
ptr->next=top->next;
923+
top->next=ptr;
924+
if (tail==top)
925+
tail=ptr;
912926
}
913927

914928
maxoff=PageGetMaxOffsetNumber(page);
@@ -964,7 +978,9 @@ gistFindPath(Relation r, BlockNumber child)
964978
top=top->next;
965979
}
966980

967-
returnNULL;
981+
elog(ERROR,"failed to re-find parent of a page in index \"%s\", block %u",
982+
RelationGetRelationName(r),child);
983+
returnNULL;/* keep compiler quiet */
968984
}
969985

970986
/*
@@ -1035,7 +1051,6 @@ gistFindCorrectParent(Relation r, GISTInsertStack *child)
10351051

10361052
/* ok, find new path */
10371053
ptr=parent=gistFindPath(r,child->blkno);
1038-
Assert(ptr!=NULL);
10391054

10401055
/* read all buffers as expected by caller */
10411056
/* note we don't lock them or gistcheckpage them here! */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp