mirror of
https://github.com/postgres/postgres.git
synced 2025-10-19 15:49:24 +03:00
Improve the IndexVacuumInfo/IndexBulkDeleteResult API to allow somewhat sane
behavior in cases where we don't know the heap tuple count accurately; in particular partial vacuum, but this also makes the API a bit more useful for ANALYZE. This patch adds "estimated_count" flags to both structs so that an approximate count can be flagged as such, and adjusts the logic so that approximate counts are not used for updating pg_class.reltuples. This fixes my previous complaint that VACUUM was putting ridiculous values into pg_class.reltuples for indexes. The actual impact of that bug is limited, because the planner only pays attention to reltuples for an index if the index is partial; which probably explains why beta testers hadn't noticed a degradation in plan quality from it. But it needs to be fixed. The whole thing is a bit messy and should be redesigned in future, because reltuples now has the potential to drift quite far away from reality when a long period elapses with no non-partial vacuums. But this is as good as it's going to get for 8.4.
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.387 2009/03/31 22:12:48 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.388 2009/06/06 22:13:51 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -3389,6 +3389,7 @@ scan_index(Relation indrel, double num_tuples)
|
||||
ivinfo.index = indrel;
|
||||
ivinfo.vacuum_full = true;
|
||||
ivinfo.analyze_only = false;
|
||||
ivinfo.estimated_count = false;
|
||||
ivinfo.message_level = elevel;
|
||||
ivinfo.num_heap_tuples = num_tuples;
|
||||
ivinfo.strategy = vac_strategy;
|
||||
@@ -3398,10 +3399,14 @@ scan_index(Relation indrel, double num_tuples)
|
||||
if (!stats)
|
||||
return;
|
||||
|
||||
/* now update statistics in pg_class */
|
||||
vac_update_relstats(indrel,
|
||||
stats->num_pages, stats->num_index_tuples,
|
||||
false, InvalidTransactionId);
|
||||
/*
|
||||
* Now update statistics in pg_class, but only if the index says the
|
||||
* count is accurate.
|
||||
*/
|
||||
if (!stats->estimated_count)
|
||||
vac_update_relstats(indrel,
|
||||
stats->num_pages, stats->num_index_tuples,
|
||||
false, InvalidTransactionId);
|
||||
|
||||
ereport(elevel,
|
||||
(errmsg("index \"%s\" now contains %.0f row versions in %u pages",
|
||||
@@ -3417,7 +3422,8 @@ scan_index(Relation indrel, double num_tuples)
|
||||
* Check for tuple count mismatch. If the index is partial, then it's OK
|
||||
* for it to have fewer tuples than the heap; else we got trouble.
|
||||
*/
|
||||
if (stats->num_index_tuples != num_tuples)
|
||||
if (!stats->estimated_count &&
|
||||
stats->num_index_tuples != num_tuples)
|
||||
{
|
||||
if (stats->num_index_tuples > num_tuples ||
|
||||
!vac_is_partial_index(indrel))
|
||||
@@ -3456,6 +3462,7 @@ vacuum_index(VacPageList vacpagelist, Relation indrel,
|
||||
ivinfo.index = indrel;
|
||||
ivinfo.vacuum_full = true;
|
||||
ivinfo.analyze_only = false;
|
||||
ivinfo.estimated_count = false;
|
||||
ivinfo.message_level = elevel;
|
||||
ivinfo.num_heap_tuples = num_tuples + keep_tuples;
|
||||
ivinfo.strategy = vac_strategy;
|
||||
@@ -3469,10 +3476,14 @@ vacuum_index(VacPageList vacpagelist, Relation indrel,
|
||||
if (!stats)
|
||||
return;
|
||||
|
||||
/* now update statistics in pg_class */
|
||||
vac_update_relstats(indrel,
|
||||
stats->num_pages, stats->num_index_tuples,
|
||||
false, InvalidTransactionId);
|
||||
/*
|
||||
* Now update statistics in pg_class, but only if the index says the
|
||||
* count is accurate.
|
||||
*/
|
||||
if (!stats->estimated_count)
|
||||
vac_update_relstats(indrel,
|
||||
stats->num_pages, stats->num_index_tuples,
|
||||
false, InvalidTransactionId);
|
||||
|
||||
ereport(elevel,
|
||||
(errmsg("index \"%s\" now contains %.0f row versions in %u pages",
|
||||
@@ -3490,7 +3501,8 @@ vacuum_index(VacPageList vacpagelist, Relation indrel,
|
||||
* Check for tuple count mismatch. If the index is partial, then it's OK
|
||||
* for it to have fewer tuples than the heap; else we got trouble.
|
||||
*/
|
||||
if (stats->num_index_tuples != num_tuples + keep_tuples)
|
||||
if (!stats->estimated_count &&
|
||||
stats->num_index_tuples != num_tuples + keep_tuples)
|
||||
{
|
||||
if (stats->num_index_tuples > num_tuples + keep_tuples ||
|
||||
!vac_is_partial_index(indrel))
|
||||
|
Reference in New Issue
Block a user