Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 774a78f

Browse files
committed
Fix GIN data page split ratio calculation.
The code that tried to split a page at 75/25 ratio, when appending to the end of an index, was buggy in two ways. First, there was a silly typo that caused it to just fill the left page as full as possible. But the logic as it was intended wasn't correct either, and would actually have given a ratio closer to 60/40 than 75/25. Gaetano Mendola spotted the typo. Backpatch to 9.4, where this code was added.
1 parent 1d35232 commit 774a78f

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

src/backend/access/gin/gindatapage.c

+17-12
Original file line numberDiff line numberDiff line change
@@ -621,19 +621,20 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
621621
/*
622622
* Had to split.
623623
*
624-
* We already divided the segments between the left and the right
625-
* page. The left page was filled as full as possible, and the rest
626-
* overflowed to the right page. When building a new index, that's
624+
* leafRepackItems already divided the segments between the left and
625+
* the right page. It filled the left page as full as possible, and
626+
* put the rest to the right page. When building a new index, that's
627627
* good, because the table is scanned from beginning to end and there
628628
* won't be any more insertions to the left page during the build.
629629
* This packs the index as tight as possible. But otherwise, split
630630
* 50/50, by moving segments from the left page to the right page
631631
* until they're balanced.
632632
*
633633
* As a further heuristic, when appending items to the end of the
634-
* page, split 75/25, one the assumption that subsequent insertions
635-
* will probably also go to the end. This packs the index somewhat
636-
* tighter when appending to a table, which is very common.
634+
* page, try make the left page 75% full, one the assumption that
635+
* subsequent insertions will probably also go to the end. This packs
636+
* the index somewhat tighter when appending to a table, which is very
637+
* common.
637638
*/
638639
if (!btree->isBuild)
639640
{
@@ -645,14 +646,18 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
645646
if (lastleftinfo->action != GIN_SEGMENT_DELETE)
646647
{
647648
segsize = SizeOfGinPostingList(lastleftinfo->seg);
649+
650+
/*
651+
* Note that we check that the right page doesn't become
652+
* more full than the left page even when appending. It's
653+
* possible that we added enough items to make both pages
654+
* more than 75% full.
655+
*/
656+
if ((leaf->lsize - segsize) - (leaf->rsize + segsize) < 0)
657+
break;
648658
if (append)
649659
{
650-
if ((leaf->lsize - segsize) - (leaf->lsize - segsize) < BLCKSZ / 4)
651-
break;
652-
}
653-
else
654-
{
655-
if ((leaf->lsize - segsize) - (leaf->rsize + segsize) < 0)
660+
if ((leaf->lsize - segsize) < (BLCKSZ * 3) / 4)
656661
break;
657662
}
658663

0 commit comments

Comments
 (0)