Skip to content

Commit 947f06c

Browse files
committed
Make gistvacuumcleanup() count the actual number of index tuples.
Previously, it just returned the heap tuple count, which might be only an estimate, and would be completely the wrong thing if the index is partial. Since this function scans every index page anyway to find free pages, it's practically free to count the surviving index tuples. Let's do that and return an accurate count. This is easily visible as a wrong reltuples value for a partial GiST index following VACUUM, so back-patch to all supported branches. Andrey Borodin, reviewed by Michail Nikolaev Discussion: https://postgr.es/m/151956654251.6915.675951950408204404.pgcf@coridan.postgresql.org
1 parent a4fed31 commit 947f06c

File tree

1 file changed

+9
-10
lines changed

1 file changed

+9
-10
lines changed

src/backend/access/gist/gistvacuum.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
3434
BlockNumber npages,
3535
blkno;
3636
BlockNumber totFreePages;
37+
double tuplesCount;
3738
bool needLock;
3839

3940
/* No-op in ANALYZE ONLY mode */
@@ -42,17 +43,7 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
4243

4344
/* Set up all-zero stats if gistbulkdelete wasn't called */
4445
if (stats == NULL)
45-
{
4646
stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
47-
/* use heap's tuple count */
48-
stats->num_index_tuples = info->num_heap_tuples;
49-
stats->estimated_count = info->estimated_count;
50-
51-
/*
52-
* XXX the above is wrong if index is partial. Would it be OK to just
53-
* return NULL, or is there work we must do below?
54-
*/
55-
}
5647

5748
/*
5849
* Need lock unless it's local to this backend.
@@ -67,6 +58,7 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
6758
UnlockRelationForExtension(rel, ExclusiveLock);
6859

6960
totFreePages = 0;
61+
tuplesCount = 0;
7062
for (blkno = GIST_ROOT_BLKNO + 1; blkno < npages; blkno++)
7163
{
7264
Buffer buffer;
@@ -84,6 +76,11 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
8476
totFreePages++;
8577
RecordFreeIndexPage(rel, blkno);
8678
}
79+
else if (GistPageIsLeaf(page))
80+
{
81+
/* count tuples in index (considering only leaf tuples) */
82+
tuplesCount += PageGetMaxOffsetNumber(page);
83+
}
8784
UnlockReleaseBuffer(buffer);
8885
}
8986

@@ -97,6 +94,8 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
9794
stats->num_pages = RelationGetNumberOfBlocks(rel);
9895
if (needLock)
9996
UnlockRelationForExtension(rel, ExclusiveLock);
97+
stats->num_index_tuples = tuplesCount;
98+
stats->estimated_count = false;
10099

101100
PG_RETURN_POINTER(stats);
102101
}

0 commit comments

Comments
 (0)