aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-09-12 11:23:59 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-09-12 11:28:58 +0300
commit79ee6370ee803b36c2649cfb7655affa2c1007f1 (patch)
treeb31ce535e43262b6fe73a4c819cba6ed1898cbc0
parent1c603198a497173b4947fc669fdeda4706b09eb8 (diff)
downloadpostgresql-79ee6370ee803b36c2649cfb7655affa2c1007f1.tar.gz
postgresql-79ee6370ee803b36c2649cfb7655affa2c1007f1.zip
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.
-rw-r--r--src/backend/access/gin/gindatapage.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c
index 0ea4f3fe284..e3ab6cfd0ee 100644
--- a/src/backend/access/gin/gindatapage.c
+++ b/src/backend/access/gin/gindatapage.c
@@ -622,9 +622,9 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
/*
* Had to split.
*
- * We already divided the segments between the left and the right
- * page. The left page was filled as full as possible, and the rest
- * overflowed to the right page. When building a new index, that's
+ * leafRepackItems already divided the segments between the left and
+ * the right page. It filled the left page as full as possible, and
+ * 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
* won't be any more insertions to the left page during the build.
* This packs the index as tight as possible. But otherwise, split
@@ -632,9 +632,10 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
* until they're balanced.
*
* As a further heuristic, when appending items to the end of the
- * page, split 75/25, one the assumption that subsequent insertions
- * will probably also go to the end. This packs the index somewhat
- * tighter when appending to a table, which is very common.
+ * page, try make the left page 75% full, one the assumption that
+ * subsequent insertions will probably also go to the end. This packs
+ * the index somewhat tighter when appending to a table, which is very
+ * common.
*/
if (!btree->isBuild)
{
@@ -646,14 +647,18 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
if (lastleftinfo->action != GIN_SEGMENT_DELETE)
{
segsize = SizeOfGinPostingList(lastleftinfo->seg);
+
+ /*
+ * 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;
if (append)
{
- if ((leaf->lsize - segsize) - (leaf->lsize - segsize) < BLCKSZ / 4)
- break;
- }
- else
- {
- if ((leaf->lsize - segsize) - (leaf->rsize + segsize) < 0)
+ if ((leaf->lsize - segsize) < (BLCKSZ * 3) / 4)
break;
}