diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index fad5cb0..85b2935 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 . + @@ -3008,7 +3015,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 + + VACUUM is currently computing heap stats. + + + + computing index stats + + VACUUM 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 38be9cf..909feb6 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 ed3acb1..e8a3388 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" @@ -204,6 +205,8 @@ analyze_rel(Oid relid, RangeVar *relation, int options, onerel->rd_rel->relkind == RELKIND_MATVIEW || onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { + pgstat_progress_start_command(PROGRESS_COMMAND_ANALYZE, + RelationGetRelid(onerel)); /* Regular table, so we'll use the regular row acquisition function */ acquirefunc = acquire_sample_rows; /* Also get regular table's size */ @@ -489,7 +492,6 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, numrows = (*acquirefunc) (onerel, elevel, rows, targrows, &totalrows, &totaldeadrows); - /* * Compute the statistics. Temporary results during the calculations for * each column are stored in a child context. The calc routines are @@ -518,6 +520,10 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, numrows, totalrows); + /* Report compute heap stats phase */ + pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE, + PROGRESS_ANALYZE_PHASE_COMPUTE_HEAP_STATS); + /* * If the appropriate flavor of the n_distinct option is * specified, override with the corresponding value. @@ -541,6 +547,10 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, rows, numrows, col_context); + /* Report compute index stats phase */ + pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE, + PROGRESS_ANALYZE_PHASE_COMPUTE_INDEX_STATS); + MemoryContextSwitchTo(old_context); MemoryContextDelete(col_context); @@ -637,6 +647,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); @@ -665,6 +678,8 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, MemoryContextSwitchTo(caller_context); MemoryContextDelete(anl_context); anl_context = NULL; + + pgstat_progress_end_command(); } /* @@ -988,6 +1003,12 @@ acquire_sample_rows(Relation onerel, int elevel, BlockSamplerData bs; ReservoirStateData rstate; + const int initprog_index[] = { + PROGRESS_ANALYZE_PHASE, + PROGRESS_ANALYZE_TOTAL_HEAP_BLKS, + }; + int64 initprog_val[2]; + Assert(targrows > 0); totalblocks = RelationGetNumberOfBlocks(onerel); @@ -1000,6 +1021,11 @@ acquire_sample_rows(Relation onerel, int elevel, /* Prepare for sampling rows */ reservoir_init_selection_state(&rstate, targrows); + /* Report total number of heap blocks and collectinf sample row phase*/ + initprog_val[0] = PROGRESS_ANALYZE_PHASE_COLLECT_HEAP_SAMPLE_ROWS; + initprog_val[1] = totalblocks; + pgstat_progress_update_multi_param(2, initprog_index, initprog_val); + /* Outer loop over blocks to sample */ while (BlockSampler_HasMore(&bs)) { @@ -1009,6 +1035,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(); /* @@ -1210,6 +1239,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..e8dae70 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 */ +#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 8b710ec..ccb7b08 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -811,7 +811,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,