Keep stats up to date for partitioned tables

In the long-going saga for analyze on partitioned tables, one thing I
missed while reverting 0827e8af70 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 6f8127b739.

Co-authored-by: Yuzuko Hosoya <yuzukohosoya@gmail.com>
Co-authored-by: Justin Pryzby <pryzby@telsasoft.com>
Co-authored-by: Álvaro Herrera <alvherre@alvh.no-ip.org>
Reported-by: Justin Pryzby <pryzby@telsasoft.com>
Discussion: https://postgr.es/m/20210816222810.GE10479@telsasoft.com
This commit is contained in:
Alvaro Herrera 2021-08-28 15:58:23 -04:00
parent 1f092a309e
commit 375aed36ad
No known key found for this signature in database
GPG Key ID: 1C20ACB9D5C564AE
2 changed files with 33 additions and 15 deletions

View File

@ -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.

View File

@ -1632,8 +1632,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;
@ -1997,8 +2000,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;