From e1efc5b465c844969a0ed0d07e1364f3ce424d8c Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Sat, 28 Aug 2021 15:58:23 -0400 Subject: [PATCH] Keep stats up to date for partitioned tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the long-going saga for analyze on partitioned tables, one thing I missed while reverting 0827e8af70f4 is the maintenance of analyze count and last analyze time for partitioned tables. This is a mostly trivial change that enables users assess the need for invoking manual ANALYZE on partitioned tables. This patch, posted by Justin and modified a bit by me (Álvaro), can be mostly traced back to Hosoya-san, though any problems introduced with the scissors are mine. Backpatch to 14, in line with 6f8127b73901. Co-authored-by: Yuzuko Hosoya Co-authored-by: Justin Pryzby Co-authored-by: Álvaro Herrera Reported-by: Justin Pryzby Discussion: https://postgr.es/m/20210816222810.GE10479@telsasoft.com --- src/backend/commands/analyze.c | 37 ++++++++++++++++++++++----------- src/backend/postmaster/pgstat.c | 11 +++++++--- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 03cdf4f5e8e..8bfb2ad9584 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -626,8 +626,8 @@ do_analyze_rel(Relation onerel, VacuumParams *params, PROGRESS_ANALYZE_PHASE_FINALIZE_ANALYZE); /* - * Update pages/tuples stats in pg_class, and report ANALYZE to the stats - * collector ... but not if we're doing inherited stats. + * Update pages/tuples stats in pg_class ... 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, @@ -668,20 +668,33 @@ do_analyze_rel(Relation onerel, VacuumParams *params, InvalidMultiXactId, in_outer_xact); } - + } + else if (onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { /* - * 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. + * Partitioned tables don't have storage, so we don't set any fields + * in their pg_class entries except for reltuples and relhasindex. */ + vac_update_relstats(onerel, -1, totalrows, + 0, hasindex, InvalidTransactionId, + InvalidMultiXactId, + in_outer_xact); + } + + /* + * Now report ANALYZE to the stats collector. For regular tables, we do + * it only if not doing inherited stats. For partitioned tables, we only + * do it for inherited stats. (We're never called for not-inherited stats + * on partitioned tables anyway.) + * + * Reset the changes_since_analyze counter only if we analyzed all + * columns; otherwise, there is still work for auto-analyze to do. + */ + if (!inh) pgstat_report_analyze(onerel, totalrows, totaldeadrows, (va_cols == NIL)); - } + else if (onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + pgstat_report_analyze(onerel, 0, 0, (va_cols == NIL)); /* * If this isn't part of VACUUM ANALYZE, let index AMs do cleanup. diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 7fcc3f6ded8..cbf763ac58d 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -1618,8 +1618,11 @@ pgstat_report_analyze(Relation rel, * be double-counted after commit. (This approach also ensures that the * collector ends up with the right numbers if we abort instead of * committing.) + * + * Waste no time on partitioned tables, though. */ - if (rel->pgstat_info != NULL) + if (rel->pgstat_info != NULL && + rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) { PgStat_TableXactStatus *trans; @@ -1981,8 +1984,10 @@ pgstat_initstats(Relation rel) Oid rel_id = rel->rd_id; char relkind = rel->rd_rel->relkind; - /* We only count stats for things that have storage */ - if (!RELKIND_HAS_STORAGE(relkind)) + /* + * We only count stats for relations with storage and partitioned tables + */ + if (!RELKIND_HAS_STORAGE(relkind) && relkind != RELKIND_PARTITIONED_TABLE) { rel->pgstat_info = NULL; return;