diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 4d03531..8aeca41 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -521,6 +521,13 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser VACUUM, showing current progress. See . + + + pg_stat_progress_analyzepg_stat_progress_analyze + One row for each backend running + ANALYZE, showing current progress. + See . + @@ -3016,7 +3023,135 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, + + + + ANALYZE Progress Reporting + + + Whenever ANALYZE is running, the + pg_stat_progress_analyze view will contain + one row for each backend that is currently analyzing. + The tables below describe the information that will be reported and + provide information about how to interpret it. + + + + <structname>pg_stat_progress_analyze</structname> View + + + + Column + Type + Description + + + + + pid + integer + Process ID of backend. + + + datid + oid + OID of the database to which this backend is connected. + + + datname + name + Name of the database to which this backend is connected. + + + relid + oid + OID of the table being vacuumed. + + + phase + text + + Current processing phase of analyze. See . + + + + heap_blks_total + bigint + + Total number of heap blocks in the table. + + + + heap_blks_scanned + bigint + + Number of heap blocks scanned. + + + + total_sample_rows + bigint + + Total number of sample rows. + + + + +
+ + + ANALYZE phases + + + + Phase + Description + + + + + + initializing + + ANALYZE is preparing to collect sample rows. + + + + collecting sample rows + + ANALYZE is currently collecting the sample rows. + The sample it reads is taken randomly.Its size depends on + the default_statistics_target parameter value. + + + + collecting inherited sample rows + + ANALYZE is currently collecting inherited sample rows. + + + + computing heap stats + + ANALYZE is currently computing heap stats. + + + + computing index stats + + ANALYZE is currently computing index stats. + + + + cleaning up indexes + + ANALYZE is currently cleaning up indexes. + + + + +
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index ba980de..90e692a 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -872,6 +872,22 @@ CREATE VIEW pg_stat_progress_vacuum AS FROM pg_stat_get_progress_info('VACUUM') AS S LEFT JOIN pg_database D ON S.datid = D.oid; +CREATE VIEW pg_stat_progress_analyze AS + SELECT + S.pid AS pid, S.datid AS datid, D.datname AS datname, + S.relid AS relid, + CASE S.param1 WHEN 0 THEN 'initializing' + WHEN 1 THEN 'collecting sample rows' + WHEN 2 THEN 'collecting inherited sample rows' + WHEN 3 THEN 'computing heap stats' + WHEN 4 THEN 'computing index stats' + WHEN 5 THEN 'cleaning up indexes' + END AS phase, + S.param2 AS heap_blks_total, S.param3 AS heap_blks_scanned, + S.param4 AS total_sample_rows + FROM pg_stat_get_progress_info('ANALYZE') AS S + LEFT JOIN pg_database D ON S.datid = D.oid; + CREATE VIEW pg_user_mappings AS SELECT U.oid AS umid, diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index b91df98..2f744f4 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -31,6 +31,7 @@ #include "commands/dbcommands.h" #include "commands/tablecmds.h" #include "commands/vacuum.h" +#include "commands/progress.h" #include "executor/executor.h" #include "foreign/fdwapi.h" #include "miscadmin.h" @@ -333,6 +334,7 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, (errmsg("analyzing \"%s.%s\"", get_namespace_name(RelationGetNamespace(onerel)), RelationGetRelationName(onerel)))); + pgstat_progress_start_command(PROGRESS_COMMAND_ANALYZE, RelationGetRelid(onerel)); /* * Set up a working context so that we can easily free whatever junk gets @@ -423,6 +425,9 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, if (hasindex) { indexdata = (AnlIndexData *) palloc0(nindexes * sizeof(AnlIndexData)); + /* Report compute index stats phase */ + pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE, + PROGRESS_ANALYZE_PHASE_COMPUTE_INDEX_STATS); for (ind = 0; ind < nindexes; ind++) { AnlIndexData *thisdata = &indexdata[ind]; @@ -488,6 +493,9 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, * Acquire the sample rows */ rows = (HeapTuple *) palloc(targrows * sizeof(HeapTuple)); + /* Report collecting sample row phase*/ + pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE, + PROGRESS_ANALYZE_PHASE_COLLECT_HEAP_SAMPLE_ROWS); if (inh) numrows = acquire_inherited_sample_rows(onerel, elevel, rows, targrows, @@ -512,6 +520,9 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, "Analyze Column", ALLOCSET_DEFAULT_SIZES); old_context = MemoryContextSwitchTo(col_context); + /* Report compute heap stats phase */ + pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE, + PROGRESS_ANALYZE_PHASE_COMPUTE_HEAP_STATS); for (i = 0; i < attr_cnt; i++) { @@ -644,6 +655,9 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, pfree(stats); } } + /* Report that we are now doing index cleanup */ + pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE, + PROGRESS_ANALYZE_PHASE_INDEX_CLEANUP); /* Done with indexes */ vac_close_indexes(nindexes, Irel, NoLock); @@ -672,6 +686,8 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, MemoryContextSwitchTo(caller_context); MemoryContextDelete(anl_context); anl_context = NULL; + + pgstat_progress_end_command(); } /* @@ -998,6 +1014,8 @@ acquire_sample_rows(Relation onerel, int elevel, Assert(targrows > 0); totalblocks = RelationGetNumberOfBlocks(onerel); + /* Report total number of heap blocks */ + pgstat_progress_update_param(PROGRESS_ANALYZE_TOTAL_HEAP_BLKS, totalblocks); /* Need a cutoff xmin for HeapTupleSatisfiesVacuum */ OldestXmin = GetOldestXmin(onerel, true); @@ -1016,6 +1034,9 @@ acquire_sample_rows(Relation onerel, int elevel, OffsetNumber targoffset, maxoffset; + /* Report number of heap blocks scaned so far*/ + pgstat_progress_update_param(PROGRESS_ANALYZE_HEAP_BLKS_SCANNED, targblock); + vacuum_delay_point(); /* @@ -1217,6 +1238,9 @@ acquire_sample_rows(Relation onerel, int elevel, liverows, deadrows, numrows, *totalrows))); + /* Report total number of sample rows*/ + pgstat_progress_update_param(PROGRESS_ANALYZE_TOTAL_SAMPLE_ROWS, numrows); + return numrows; } diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index a987d0d..eb1dd63 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -465,6 +465,8 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS) /* Translate command name into command type code. */ if (pg_strcasecmp(cmd, "VACUUM") == 0) cmdtype = PROGRESS_COMMAND_VACUUM; + else if (pg_strcasecmp(cmd, "ANALYZE") == 0) + cmdtype = PROGRESS_COMMAND_ANALYZE; else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h index 9472ecc..6423e5a 100644 --- a/src/include/commands/progress.h +++ b/src/include/commands/progress.h @@ -34,4 +34,17 @@ #define PROGRESS_VACUUM_PHASE_TRUNCATE 5 #define PROGRESS_VACUUM_PHASE_FINAL_CLEANUP 6 +/* Progress parameters for analyze */ +#define PROGRESS_ANALYZE_PHASE 0 +#define PROGRESS_ANALYZE_TOTAL_HEAP_BLKS 1 +#define PROGRESS_ANALYZE_HEAP_BLKS_SCANNED 2 +#define PROGRESS_ANALYZE_TOTAL_SAMPLE_ROWS 3 + +/* Phases of analyze (as advertised via PROGRESS_ANALYZE_PHASE) */ +#define PROGRESS_ANALYZE_PHASE_COLLECT_HEAP_SAMPLE_ROWS 1 +#define PROGRESS_ANALYZE_PHASE_COLLECT_INH_SAMPLE_ROWS 2 +#define PROGRESS_ANALYZE_PHASE_COMPUTE_HEAP_STATS 3 +#define PROGRESS_ANALYZE_PHASE_COMPUTE_INDEX_STATS 4 +#define PROGRESS_ANALYZE_PHASE_INDEX_CLEANUP 5 + #endif diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 60c78d1..2b51d76 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -812,7 +812,8 @@ typedef enum typedef enum ProgressCommandType { PROGRESS_COMMAND_INVALID, - PROGRESS_COMMAND_VACUUM + PROGRESS_COMMAND_VACUUM, + PROGRESS_COMMAND_ANALYZE } ProgressCommandType; #define PGSTAT_NUM_PROGRESS_PARAM 10 diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index c661f1d..a01c464 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1817,6 +1817,24 @@ pg_stat_progress_vacuum| SELECT s.pid, s.param7 AS num_dead_tuples FROM (pg_stat_get_progress_info('VACUUM'::text) s(pid, datid, relid, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) LEFT JOIN pg_database d ON ((s.datid = d.oid))); +pg_stat_progress_analyze| SELECT s.pid, + s.datid, + d.datname, + s.relid, + CASE s.param1 + WHEN 0 THEN 'initializing'::text + WHEN 1 THEN 'collecting sample rows'::text + WHEN 2 THEN 'collecting inherited sample rows'::text + WHEN 3 THEN 'computing heap stats'::text + WHEN 4 THEN 'computing index stats'::text + WHEN 5 THEN 'cleaning up indexes'::text + ELSE NULL::text + END AS phase, + s.param2 AS heap_blks_total, + s.param3 AS heap_blks_scanned, + s.param4 AS total_sample_rows, + FROM (pg_stat_get_progress_info('ANALYZE'::text) s(pid, datid, relid, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) + LEFT JOIN pg_database d ON ((s.datid = d.oid))); pg_stat_replication| SELECT s.pid, s.usesysid, u.rolname AS usename,