mirror of
https://github.com/postgres/postgres.git
synced 2025-04-29 13:56:47 +03:00
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
This commit is contained in:
parent
fb1d72f409
commit
46d98da43e
@ -34,6 +34,7 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
|
|||||||
BlockNumber npages,
|
BlockNumber npages,
|
||||||
blkno;
|
blkno;
|
||||||
BlockNumber totFreePages;
|
BlockNumber totFreePages;
|
||||||
|
double tuplesCount;
|
||||||
bool needLock;
|
bool needLock;
|
||||||
|
|
||||||
/* No-op in ANALYZE ONLY mode */
|
/* No-op in ANALYZE ONLY mode */
|
||||||
@ -42,17 +43,7 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
/* Set up all-zero stats if gistbulkdelete wasn't called */
|
/* Set up all-zero stats if gistbulkdelete wasn't called */
|
||||||
if (stats == NULL)
|
if (stats == NULL)
|
||||||
{
|
|
||||||
stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
|
stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
|
||||||
/* use heap's tuple count */
|
|
||||||
stats->num_index_tuples = info->num_heap_tuples;
|
|
||||||
stats->estimated_count = info->estimated_count;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX the above is wrong if index is partial. Would it be OK to just
|
|
||||||
* return NULL, or is there work we must do below?
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Need lock unless it's local to this backend.
|
* Need lock unless it's local to this backend.
|
||||||
@ -67,6 +58,7 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
|
|||||||
UnlockRelationForExtension(rel, ExclusiveLock);
|
UnlockRelationForExtension(rel, ExclusiveLock);
|
||||||
|
|
||||||
totFreePages = 0;
|
totFreePages = 0;
|
||||||
|
tuplesCount = 0;
|
||||||
for (blkno = GIST_ROOT_BLKNO + 1; blkno < npages; blkno++)
|
for (blkno = GIST_ROOT_BLKNO + 1; blkno < npages; blkno++)
|
||||||
{
|
{
|
||||||
Buffer buffer;
|
Buffer buffer;
|
||||||
@ -84,6 +76,11 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
|
|||||||
totFreePages++;
|
totFreePages++;
|
||||||
RecordFreeIndexPage(rel, blkno);
|
RecordFreeIndexPage(rel, blkno);
|
||||||
}
|
}
|
||||||
|
else if (GistPageIsLeaf(page))
|
||||||
|
{
|
||||||
|
/* count tuples in index (considering only leaf tuples) */
|
||||||
|
tuplesCount += PageGetMaxOffsetNumber(page);
|
||||||
|
}
|
||||||
UnlockReleaseBuffer(buffer);
|
UnlockReleaseBuffer(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +94,8 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
|
|||||||
stats->num_pages = RelationGetNumberOfBlocks(rel);
|
stats->num_pages = RelationGetNumberOfBlocks(rel);
|
||||||
if (needLock)
|
if (needLock)
|
||||||
UnlockRelationForExtension(rel, ExclusiveLock);
|
UnlockRelationForExtension(rel, ExclusiveLock);
|
||||||
|
stats->num_index_tuples = tuplesCount;
|
||||||
|
stats->estimated_count = false;
|
||||||
|
|
||||||
PG_RETURN_POINTER(stats);
|
PG_RETURN_POINTER(stats);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user