mirror of
https://github.com/postgres/postgres.git
synced 2025-11-22 12:22:45 +03:00
Track per-relation cumulative time spent in [auto]vacuum and [auto]analyze
This commit adds four fields to the statistics of relations, aggregating the amount of time spent for each operation on a relation: - total_vacuum_time, for manual vacuum. - total_autovacuum_time, for vacuum done by the autovacuum daemon. - total_analyze_time, for manual analyze. - total_autoanalyze_time, for analyze done by the autovacuum daemon. This gives users the option to derive the average time spent for these operations with the help of the related "count" fields. Bump catalog version (for the catalog changes) and PGSTAT_FILE_FORMAT_ID (for the additions in PgStat_StatTabEntry). Author: Sami Imseih Reviewed-by: Bertrand Drouvot, Michael Paquier Discussion: https://postgr.es/m/CAA5RZ0uVOGBYmPEeGF2d1B_67tgNjKx_bKDuL+oUftuoz+=Y1g@mail.gmail.com
This commit is contained in:
@@ -386,7 +386,6 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
|
||||
if (instrument)
|
||||
{
|
||||
pg_rusage_init(&ru0);
|
||||
starttime = GetCurrentTimestamp();
|
||||
if (track_io_timing)
|
||||
{
|
||||
startreadtime = pgStatBlockReadTime;
|
||||
@@ -394,6 +393,9 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
|
||||
}
|
||||
}
|
||||
|
||||
/* Used for instrumentation and stats report */
|
||||
starttime = GetCurrentTimestamp();
|
||||
|
||||
pgstat_progress_start_command(PROGRESS_COMMAND_VACUUM,
|
||||
RelationGetRelid(rel));
|
||||
|
||||
@@ -659,7 +661,8 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
|
||||
rel->rd_rel->relisshared,
|
||||
Max(vacrel->new_live_tuples, 0),
|
||||
vacrel->recently_dead_tuples +
|
||||
vacrel->missed_dead_tuples);
|
||||
vacrel->missed_dead_tuples,
|
||||
starttime);
|
||||
pgstat_progress_end_command();
|
||||
|
||||
if (instrument)
|
||||
|
||||
@@ -696,7 +696,11 @@ CREATE VIEW pg_stat_all_tables AS
|
||||
pg_stat_get_vacuum_count(C.oid) AS vacuum_count,
|
||||
pg_stat_get_autovacuum_count(C.oid) AS autovacuum_count,
|
||||
pg_stat_get_analyze_count(C.oid) AS analyze_count,
|
||||
pg_stat_get_autoanalyze_count(C.oid) AS autoanalyze_count
|
||||
pg_stat_get_autoanalyze_count(C.oid) AS autoanalyze_count,
|
||||
pg_stat_get_total_vacuum_time(C.oid) AS total_vacuum_time,
|
||||
pg_stat_get_total_autovacuum_time(C.oid) AS total_autovacuum_time,
|
||||
pg_stat_get_total_analyze_time(C.oid) AS total_analyze_time,
|
||||
pg_stat_get_total_autoanalyze_time(C.oid) AS total_autoanalyze_time
|
||||
FROM pg_class C LEFT JOIN
|
||||
pg_index I ON C.oid = I.indrelid
|
||||
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
|
||||
|
||||
@@ -344,8 +344,8 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
|
||||
RestrictSearchPath();
|
||||
|
||||
/*
|
||||
* measure elapsed time if called with verbose or if autovacuum logging
|
||||
* requires it
|
||||
* When verbose or autovacuum logging is used, initialize a resource usage
|
||||
* snapshot and optionally track I/O timing.
|
||||
*/
|
||||
if (instrument)
|
||||
{
|
||||
@@ -356,9 +356,11 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
|
||||
}
|
||||
|
||||
pg_rusage_init(&ru0);
|
||||
starttime = GetCurrentTimestamp();
|
||||
}
|
||||
|
||||
/* Used for instrumentation and stats report */
|
||||
starttime = GetCurrentTimestamp();
|
||||
|
||||
/*
|
||||
* Determine which columns to analyze
|
||||
*
|
||||
@@ -693,9 +695,9 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
|
||||
*/
|
||||
if (!inh)
|
||||
pgstat_report_analyze(onerel, totalrows, totaldeadrows,
|
||||
(va_cols == NIL));
|
||||
(va_cols == NIL), starttime);
|
||||
else if (onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
|
||||
pgstat_report_analyze(onerel, 0, 0, (va_cols == NIL));
|
||||
pgstat_report_analyze(onerel, 0, 0, (va_cols == NIL), starttime);
|
||||
|
||||
/*
|
||||
* If this isn't part of VACUUM ANALYZE, let index AMs do cleanup.
|
||||
|
||||
@@ -208,19 +208,22 @@ pgstat_drop_relation(Relation rel)
|
||||
*/
|
||||
void
|
||||
pgstat_report_vacuum(Oid tableoid, bool shared,
|
||||
PgStat_Counter livetuples, PgStat_Counter deadtuples)
|
||||
PgStat_Counter livetuples, PgStat_Counter deadtuples,
|
||||
TimestampTz starttime)
|
||||
{
|
||||
PgStat_EntryRef *entry_ref;
|
||||
PgStatShared_Relation *shtabentry;
|
||||
PgStat_StatTabEntry *tabentry;
|
||||
Oid dboid = (shared ? InvalidOid : MyDatabaseId);
|
||||
TimestampTz ts;
|
||||
PgStat_Counter elapsedtime;
|
||||
|
||||
if (!pgstat_track_counts)
|
||||
return;
|
||||
|
||||
/* Store the data in the table's hash table entry. */
|
||||
ts = GetCurrentTimestamp();
|
||||
elapsedtime = TimestampDifferenceMilliseconds(starttime, ts);
|
||||
|
||||
/* block acquiring lock for the same reason as pgstat_report_autovac() */
|
||||
entry_ref = pgstat_get_entry_ref_locked(PGSTAT_KIND_RELATION,
|
||||
@@ -248,11 +251,13 @@ pgstat_report_vacuum(Oid tableoid, bool shared,
|
||||
{
|
||||
tabentry->last_autovacuum_time = ts;
|
||||
tabentry->autovacuum_count++;
|
||||
tabentry->total_autovacuum_time += elapsedtime;
|
||||
}
|
||||
else
|
||||
{
|
||||
tabentry->last_vacuum_time = ts;
|
||||
tabentry->vacuum_count++;
|
||||
tabentry->total_vacuum_time += elapsedtime;
|
||||
}
|
||||
|
||||
pgstat_unlock_entry(entry_ref);
|
||||
@@ -276,12 +281,14 @@ pgstat_report_vacuum(Oid tableoid, bool shared,
|
||||
void
|
||||
pgstat_report_analyze(Relation rel,
|
||||
PgStat_Counter livetuples, PgStat_Counter deadtuples,
|
||||
bool resetcounter)
|
||||
bool resetcounter, TimestampTz starttime)
|
||||
{
|
||||
PgStat_EntryRef *entry_ref;
|
||||
PgStatShared_Relation *shtabentry;
|
||||
PgStat_StatTabEntry *tabentry;
|
||||
Oid dboid = (rel->rd_rel->relisshared ? InvalidOid : MyDatabaseId);
|
||||
TimestampTz ts;
|
||||
PgStat_Counter elapsedtime;
|
||||
|
||||
if (!pgstat_track_counts)
|
||||
return;
|
||||
@@ -315,6 +322,10 @@ pgstat_report_analyze(Relation rel,
|
||||
deadtuples = Max(deadtuples, 0);
|
||||
}
|
||||
|
||||
/* Store the data in the table's hash table entry. */
|
||||
ts = GetCurrentTimestamp();
|
||||
elapsedtime = TimestampDifferenceMilliseconds(starttime, ts);
|
||||
|
||||
/* block acquiring lock for the same reason as pgstat_report_autovac() */
|
||||
entry_ref = pgstat_get_entry_ref_locked(PGSTAT_KIND_RELATION, dboid,
|
||||
RelationGetRelid(rel),
|
||||
@@ -338,13 +349,15 @@ pgstat_report_analyze(Relation rel,
|
||||
|
||||
if (AmAutoVacuumWorkerProcess())
|
||||
{
|
||||
tabentry->last_autoanalyze_time = GetCurrentTimestamp();
|
||||
tabentry->last_autoanalyze_time = ts;
|
||||
tabentry->autoanalyze_count++;
|
||||
tabentry->total_autoanalyze_time += elapsedtime;
|
||||
}
|
||||
else
|
||||
{
|
||||
tabentry->last_analyze_time = GetCurrentTimestamp();
|
||||
tabentry->last_analyze_time = ts;
|
||||
tabentry->analyze_count++;
|
||||
tabentry->total_analyze_time += elapsedtime;
|
||||
}
|
||||
|
||||
pgstat_unlock_entry(entry_ref);
|
||||
|
||||
@@ -106,6 +106,34 @@ PG_STAT_GET_RELENTRY_INT64(tuples_updated)
|
||||
/* pg_stat_get_vacuum_count */
|
||||
PG_STAT_GET_RELENTRY_INT64(vacuum_count)
|
||||
|
||||
#define PG_STAT_GET_RELENTRY_FLOAT8(stat) \
|
||||
Datum \
|
||||
CppConcat(pg_stat_get_,stat)(PG_FUNCTION_ARGS) \
|
||||
{ \
|
||||
Oid relid = PG_GETARG_OID(0); \
|
||||
double result; \
|
||||
PgStat_StatTabEntry *tabentry; \
|
||||
\
|
||||
if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL) \
|
||||
result = 0; \
|
||||
else \
|
||||
result = (double) (tabentry->stat); \
|
||||
\
|
||||
PG_RETURN_FLOAT8(result); \
|
||||
}
|
||||
|
||||
/* pg_stat_get_total_vacuum_time */
|
||||
PG_STAT_GET_RELENTRY_FLOAT8(total_vacuum_time)
|
||||
|
||||
/* pg_stat_get_total_autovacuum_time */
|
||||
PG_STAT_GET_RELENTRY_FLOAT8(total_autovacuum_time)
|
||||
|
||||
/* pg_stat_get_total_analyze_time */
|
||||
PG_STAT_GET_RELENTRY_FLOAT8(total_analyze_time)
|
||||
|
||||
/* pg_stat_get_total_autoanalyze_time */
|
||||
PG_STAT_GET_RELENTRY_FLOAT8(total_autoanalyze_time)
|
||||
|
||||
#define PG_STAT_GET_RELENTRY_TIMESTAMPTZ(stat) \
|
||||
Datum \
|
||||
CppConcat(pg_stat_get_,stat)(PG_FUNCTION_ARGS) \
|
||||
|
||||
Reference in New Issue
Block a user