Commit 774a78ff authored by Heikki Linnakangas's avatar Heikki Linnakangas

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.
parent 1d352325
...@@ -621,9 +621,9 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack, ...@@ -621,9 +621,9 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
/* /*
* Had to split. * Had to split.
* *
* We already divided the segments between the left and the right * leafRepackItems already divided the segments between the left and
* page. The left page was filled as full as possible, and the rest * the right page. It filled the left page as full as possible, and
* overflowed to the right page. When building a new index, that's * put the rest to the right page. When building a new index, that's
* good, because the table is scanned from beginning to end and there * good, because the table is scanned from beginning to end and there
* won't be any more insertions to the left page during the build. * won't be any more insertions to the left page during the build.
* This packs the index as tight as possible. But otherwise, split * This packs the index as tight as possible. But otherwise, split
...@@ -631,9 +631,10 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack, ...@@ -631,9 +631,10 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
* until they're balanced. * until they're balanced.
* *
* As a further heuristic, when appending items to the end of the * As a further heuristic, when appending items to the end of the
* page, split 75/25, one the assumption that subsequent insertions * page, try make the left page 75% full, one the assumption that
* will probably also go to the end. This packs the index somewhat * subsequent insertions will probably also go to the end. This packs
* tighter when appending to a table, which is very common. * the index somewhat tighter when appending to a table, which is very
* common.
*/ */
if (!btree->isBuild) if (!btree->isBuild)
{ {
...@@ -645,14 +646,18 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack, ...@@ -645,14 +646,18 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
if (lastleftinfo->action != GIN_SEGMENT_DELETE) if (lastleftinfo->action != GIN_SEGMENT_DELETE)
{ {
segsize = SizeOfGinPostingList(lastleftinfo->seg); segsize = SizeOfGinPostingList(lastleftinfo->seg);
if (append)
{ /*
if ((leaf->lsize - segsize) - (leaf->lsize - segsize) < BLCKSZ / 4) * Note that we check that the right page doesn't become
* more full than the left page even when appending. It's
* possible that we added enough items to make both pages
* more than 75% full.
*/
if ((leaf->lsize - segsize) - (leaf->rsize + segsize) < 0)
break; break;
} if (append)
else
{ {
if ((leaf->lsize - segsize) - (leaf->rsize + segsize) < 0) if ((leaf->lsize - segsize) < (BLCKSZ * 3) / 4)
break; break;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment