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

Commit 79ee637

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 1c60319 commit 79ee637

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

0 commit comments

Comments
 (0)