diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 4b65205cd13..a65dcbebfa8 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -1738,7 +1738,8 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, end_parallel_vacuum(indstats, lps, nindexes); /* Update index statistics */ - update_index_statistics(Irel, indstats, nindexes); + if (vacrelstats->useindex) + update_index_statistics(Irel, indstats, nindexes); /* If no indexes, make log report that lazy_vacuum_heap would've made */ if (vacuumed_pages) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 7295cf02156..3a9f358dd4f 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -600,8 +600,16 @@ do_analyze_rel(Relation onerel, VacuumParams *params, PROGRESS_ANALYZE_PHASE_FINALIZE_ANALYZE); /* - * Update pages/tuples stats in pg_class ... but not if we're doing - * inherited stats. + * Update pages/tuples stats in pg_class, and report ANALYZE to the stats + * collector ... but not if we're doing inherited stats. + * + * We assume that VACUUM hasn't set pg_class.reltuples already, even + * during a VACUUM ANALYZE. Although VACUUM often updates pg_class, + * exceptions exists. A "VACUUM (ANALYZE, INDEX_CLEANUP OFF)" command + * will never update pg_class entries for index relations. It's also + * possible that an individual index's pg_class entry won't be updated + * during VACUUM if the index AM returns NULL from its amvacuumcleanup() + * routine. */ if (!inh) { @@ -609,6 +617,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params, visibilitymap_count(onerel, &relallvisible, NULL); + /* Update pg_class for table relation */ vac_update_relstats(onerel, relpages, totalrows, @@ -617,15 +626,8 @@ do_analyze_rel(Relation onerel, VacuumParams *params, InvalidTransactionId, InvalidMultiXactId, in_outer_xact); - } - /* - * Same for indexes. Vacuum always scans all indexes, so if we're part of - * VACUUM ANALYZE, don't overwrite the accurate count already inserted by - * VACUUM. - */ - if (!inh && !(params->options & VACOPT_VACUUM)) - { + /* Same for indexes */ for (ind = 0; ind < nindexes; ind++) { AnlIndexData *thisdata = &indexdata[ind]; @@ -641,20 +643,28 @@ do_analyze_rel(Relation onerel, VacuumParams *params, InvalidMultiXactId, in_outer_xact); } + + /* + * Now report ANALYZE to the stats collector. + * + * We deliberately don't report to the stats collector when doing + * inherited stats, because the stats collector only tracks per-table + * stats. + * + * Reset the changes_since_analyze counter only if we analyzed all + * columns; otherwise, there is still work for auto-analyze to do. + */ + pgstat_report_analyze(onerel, totalrows, totaldeadrows, + (va_cols == NIL)); } /* - * Report ANALYZE to the stats collector, too. However, if doing - * inherited stats we shouldn't report, because the stats collector only - * tracks per-table stats. Reset the changes_since_analyze counter only - * if we analyzed all columns; otherwise, there is still work for - * auto-analyze to do. + * If this isn't part of VACUUM ANALYZE, let index AMs do cleanup. + * + * Note that most index AMs perform a no-op as a matter of policy for + * amvacuumcleanup() when called in ANALYZE-only mode. The only exception + * among core index AMs is GIN/ginvacuumcleanup(). */ - if (!inh) - pgstat_report_analyze(onerel, totalrows, totaldeadrows, - (va_cols == NIL)); - - /* If this isn't part of VACUUM ANALYZE, let index AMs do cleanup */ if (!(params->options & VACOPT_VACUUM)) { for (ind = 0; ind < nindexes; ind++)