diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/catalog/system_views.sql | 21 | ||||
-rw-r--r-- | src/backend/commands/analyze.c | 33 | ||||
-rw-r--r-- | src/backend/statistics/extended_stats.c | 23 | ||||
-rw-r--r-- | src/backend/utils/adt/pgstatfuncs.c | 2 | ||||
-rw-r--r-- | src/backend/utils/misc/sampling.c | 6 | ||||
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/commands/progress.h | 17 | ||||
-rw-r--r-- | src/include/pgstat.h | 1 | ||||
-rw-r--r-- | src/include/utils/sampling.h | 4 | ||||
-rw-r--r-- | src/test/regress/expected/rules.out | 22 |
10 files changed, 126 insertions, 5 deletions
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 773edf85e78..b3e82de71e6 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -957,6 +957,27 @@ CREATE VIEW pg_stat_bgwriter AS pg_stat_get_buf_alloc() AS buffers_alloc, pg_stat_get_bgwriter_stat_reset_time() AS stats_reset; +CREATE VIEW pg_stat_progress_analyze AS + SELECT + S.pid AS pid, S.datid AS datid, D.datname AS datname, + CAST(S.relid AS oid) AS relid, + CASE S.param1 WHEN 0 THEN 'initializing' + WHEN 1 THEN 'acquiring sample rows' + WHEN 2 THEN 'acquiring inherited sample rows' + WHEN 3 THEN 'computing statistics' + WHEN 4 THEN 'computing extended statistics' + WHEN 5 THEN 'finalizing analyze' + END AS phase, + S.param2 AS sample_blks_total, + S.param3 AS sample_blks_scanned, + S.param4 AS ext_stats_total, + S.param5 AS ext_stats_computed, + S.param6 AS child_tables_total, + S.param7 AS child_tables_done, + CAST(S.param8 AS oid) AS current_child_table_relid + FROM pg_stat_get_progress_info('ANALYZE') AS S + LEFT JOIN pg_database D ON S.datid = D.oid; + CREATE VIEW pg_stat_progress_vacuum AS SELECT S.pid AS pid, S.datid AS datid, D.datname AS datname, diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 53b11d7f09b..c4420ddd7f2 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -35,6 +35,7 @@ #include "catalog/pg_namespace.h" #include "catalog/pg_statistic_ext.h" #include "commands/dbcommands.h" +#include "commands/progress.h" #include "commands/tablecmds.h" #include "commands/vacuum.h" #include "executor/executor.h" @@ -251,6 +252,8 @@ analyze_rel(Oid relid, RangeVar *relation, LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); MyPgXact->vacuumFlags |= PROC_IN_ANALYZE; LWLockRelease(ProcArrayLock); + pgstat_progress_start_command(PROGRESS_COMMAND_ANALYZE, + RelationGetRelid(onerel)); /* * Do the normal non-recursive ANALYZE. We can skip this for partitioned @@ -275,6 +278,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ relation_close(onerel, NoLock); + pgstat_progress_end_command(); + /* * Reset my PGXACT flag. Note: we need this here, and not in vacuum_rel, * because the vacuum flag is cleared by the end-of-xact code. @@ -506,6 +511,9 @@ do_analyze_rel(Relation onerel, VacuumParams *params, * Acquire the sample rows */ rows = (HeapTuple *) palloc(targrows * sizeof(HeapTuple)); + pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE, + inh ? PROGRESS_ANALYZE_PHASE_ACQUIRE_SAMPLE_ROWS_INH : + PROGRESS_ANALYZE_PHASE_ACQUIRE_SAMPLE_ROWS); if (inh) numrows = acquire_inherited_sample_rows(onerel, elevel, rows, targrows, @@ -526,6 +534,9 @@ do_analyze_rel(Relation onerel, VacuumParams *params, MemoryContext col_context, old_context; + pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE, + PROGRESS_ANALYZE_PHASE_COMPUTE_STATS); + col_context = AllocSetContextCreate(anl_context, "Analyze Column", ALLOCSET_DEFAULT_SIZES); @@ -596,6 +607,9 @@ do_analyze_rel(Relation onerel, VacuumParams *params, attr_cnt, vacattrstats); } + pgstat_progress_update_param(PROGRESS_ANALYZE_PHASE, + PROGRESS_ANALYZE_PHASE_FINALIZE_ANALYZE); + /* * Update pages/tuples stats in pg_class ... but not if we're doing * inherited stats. @@ -1034,6 +1048,8 @@ acquire_sample_rows(Relation onerel, int elevel, ReservoirStateData rstate; TupleTableSlot *slot; TableScanDesc scan; + BlockNumber nblocks; + BlockNumber blksdone = 0; Assert(targrows > 0); @@ -1043,7 +1059,12 @@ acquire_sample_rows(Relation onerel, int elevel, OldestXmin = GetOldestXmin(onerel, PROCARRAY_FLAGS_VACUUM); /* Prepare for sampling block numbers */ - BlockSampler_Init(&bs, totalblocks, targrows, random()); + nblocks = BlockSampler_Init(&bs, totalblocks, targrows, random()); + + /* Report sampling block numbers */ + pgstat_progress_update_param(PROGRESS_ANALYZE_BLOCKS_TOTAL, + nblocks); + /* Prepare for sampling rows */ reservoir_init_selection_state(&rstate, targrows); @@ -1104,6 +1125,9 @@ acquire_sample_rows(Relation onerel, int elevel, samplerows += 1; } + + pgstat_progress_update_param(PROGRESS_ANALYZE_BLOCKS_DONE, + ++blksdone); } ExecDropSingleTupleTableSlot(slot); @@ -1332,6 +1356,8 @@ acquire_inherited_sample_rows(Relation onerel, int elevel, * rels have radically different free-space percentages, but it's not * clear that it's worth working harder.) */ + pgstat_progress_update_param(PROGRESS_ANALYZE_CHILD_TABLES_TOTAL, + nrels); numrows = 0; *totalrows = 0; *totaldeadrows = 0; @@ -1341,6 +1367,9 @@ acquire_inherited_sample_rows(Relation onerel, int elevel, AcquireSampleRowsFunc acquirefunc = acquirefuncs[i]; double childblocks = relblocks[i]; + pgstat_progress_update_param(PROGRESS_ANALYZE_CURRENT_CHILD_TABLE_RELID, + RelationGetRelid(childrel)); + if (childblocks > 0) { int childtargrows; @@ -1396,6 +1425,8 @@ acquire_inherited_sample_rows(Relation onerel, int elevel, * pointers to their TOAST tables in the sampled rows. */ table_close(childrel, NoLock); + pgstat_progress_update_param(PROGRESS_ANALYZE_CHILD_TABLES_DONE, + i + 1); } return numrows; diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c index d17b8d9b1f2..03e69d057ff 100644 --- a/src/backend/statistics/extended_stats.c +++ b/src/backend/statistics/extended_stats.c @@ -24,10 +24,12 @@ #include "catalog/pg_collation.h" #include "catalog/pg_statistic_ext.h" #include "catalog/pg_statistic_ext_data.h" +#include "commands/progress.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/optimizer.h" +#include "pgstat.h" #include "postmaster/autovacuum.h" #include "statistics/extended_stats_internal.h" #include "statistics/statistics.h" @@ -92,6 +94,7 @@ BuildRelationExtStatistics(Relation onerel, double totalrows, List *stats; MemoryContext cxt; MemoryContext oldcxt; + int64 ext_cnt; cxt = AllocSetContextCreate(CurrentMemoryContext, "BuildRelationExtStatistics", @@ -101,6 +104,22 @@ BuildRelationExtStatistics(Relation onerel, double totalrows, pg_stext = table_open(StatisticExtRelationId, RowExclusiveLock); stats = fetch_statentries_for_relation(pg_stext, RelationGetRelid(onerel)); + /* report this phase */ + if (stats != NIL) + { + const int index[] = { + PROGRESS_ANALYZE_PHASE, + PROGRESS_ANALYZE_EXT_STATS_TOTAL + }; + const int64 val[] = { + PROGRESS_ANALYZE_PHASE_COMPUTE_EXT_STATS, + list_length(stats) + }; + + pgstat_progress_update_multi_param(2, index, val); + } + + ext_cnt = 0; foreach(lc, stats) { StatExtEntry *stat = (StatExtEntry *) lfirst(lc); @@ -165,6 +184,10 @@ BuildRelationExtStatistics(Relation onerel, double totalrows, /* store the statistics in the catalog */ statext_store(stat->statOid, ndistinct, dependencies, mcv, stats); + + /* for reporting progress */ + pgstat_progress_update_param(PROGRESS_ANALYZE_EXT_STATS_COMPUTED, + ++ext_cnt); } table_close(pg_stext, RowExclusiveLock); diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 3dbf6048acb..74f899f24df 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -468,6 +468,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 if (pg_strcasecmp(cmd, "CLUSTER") == 0) cmdtype = PROGRESS_COMMAND_CLUSTER; else if (pg_strcasecmp(cmd, "CREATE INDEX") == 0) diff --git a/src/backend/utils/misc/sampling.c b/src/backend/utils/misc/sampling.c index daf75ee5d97..361c15614e7 100644 --- a/src/backend/utils/misc/sampling.c +++ b/src/backend/utils/misc/sampling.c @@ -32,8 +32,10 @@ * Since we know the total number of blocks in advance, we can use the * straightforward Algorithm S from Knuth 3.4.2, rather than Vitter's * algorithm. + * + * Returns the number of blocks that BlockSampler_Next will return. */ -void +BlockNumber BlockSampler_Init(BlockSampler bs, BlockNumber nblocks, int samplesize, long randseed) { @@ -48,6 +50,8 @@ BlockSampler_Init(BlockSampler bs, BlockNumber nblocks, int samplesize, bs->m = 0; /* blocks selected so far */ sampler_random_init_state(randseed, bs->randstate); + + return Min(bs->n, bs->N); } bool diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 40c1e8e0b85..6ac57be6a08 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202001091 +#define CATALOG_VERSION_NO 202001151 #endif diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h index 3f91b3bf525..12e9d3d42f8 100644 --- a/src/include/commands/progress.h +++ b/src/include/commands/progress.h @@ -34,6 +34,23 @@ #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_BLOCKS_TOTAL 1 +#define PROGRESS_ANALYZE_BLOCKS_DONE 2 +#define PROGRESS_ANALYZE_EXT_STATS_TOTAL 3 +#define PROGRESS_ANALYZE_EXT_STATS_COMPUTED 4 +#define PROGRESS_ANALYZE_CHILD_TABLES_TOTAL 5 +#define PROGRESS_ANALYZE_CHILD_TABLES_DONE 6 +#define PROGRESS_ANALYZE_CURRENT_CHILD_TABLE_RELID 7 + +/* Phases of analyze (as advertised via PROGRESS_ANALYZE_PHASE) */ +#define PROGRESS_ANALYZE_PHASE_ACQUIRE_SAMPLE_ROWS 1 +#define PROGRESS_ANALYZE_PHASE_ACQUIRE_SAMPLE_ROWS_INH 2 +#define PROGRESS_ANALYZE_PHASE_COMPUTE_STATS 3 +#define PROGRESS_ANALYZE_PHASE_COMPUTE_EXT_STATS 4 +#define PROGRESS_ANALYZE_PHASE_FINALIZE_ANALYZE 5 + /* Progress parameters for cluster */ #define PROGRESS_CLUSTER_COMMAND 0 #define PROGRESS_CLUSTER_PHASE 1 diff --git a/src/include/pgstat.h b/src/include/pgstat.h index e5a5d025ba6..36b530bc27f 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -956,6 +956,7 @@ typedef enum ProgressCommandType { PROGRESS_COMMAND_INVALID, PROGRESS_COMMAND_VACUUM, + PROGRESS_COMMAND_ANALYZE, PROGRESS_COMMAND_CLUSTER, PROGRESS_COMMAND_CREATE_INDEX } ProgressCommandType; diff --git a/src/include/utils/sampling.h b/src/include/utils/sampling.h index a84914b968a..74646846b20 100644 --- a/src/include/utils/sampling.h +++ b/src/include/utils/sampling.h @@ -37,8 +37,8 @@ typedef struct typedef BlockSamplerData *BlockSampler; -extern void BlockSampler_Init(BlockSampler bs, BlockNumber nblocks, - int samplesize, long randseed); +extern BlockNumber BlockSampler_Init(BlockSampler bs, BlockNumber nblocks, + int samplesize, long randseed); extern bool BlockSampler_HasMore(BlockSampler bs); extern BlockNumber BlockSampler_Next(BlockSampler bs); diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 62eaf90a0f2..70e1e2f78d1 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1852,6 +1852,28 @@ pg_stat_gssapi| SELECT s.pid, s.gss_enc AS encrypted FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc) WHERE (s.client_port IS NOT NULL); +pg_stat_progress_analyze| SELECT s.pid, + s.datid, + d.datname, + s.relid, + CASE s.param1 + WHEN 0 THEN 'initializing'::text + WHEN 1 THEN 'acquiring sample rows'::text + WHEN 2 THEN 'acquiring inherited sample rows'::text + WHEN 3 THEN 'computing statistics'::text + WHEN 4 THEN 'computing extended statistics'::text + WHEN 5 THEN 'finalizing analyze'::text + ELSE NULL::text + END AS phase, + s.param2 AS sample_blks_total, + s.param3 AS sample_blks_scanned, + s.param4 AS ext_stats_total, + s.param5 AS ext_stats_computed, + s.param6 AS child_tables_total, + s.param7 AS child_tables_done, + (s.param8)::oid AS current_child_table_relid + FROM (pg_stat_get_progress_info('ANALYZE'::text) s(pid, datid, relid, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16, param17, param18, param19, param20) + LEFT JOIN pg_database d ON ((s.datid = d.oid))); pg_stat_progress_cluster| SELECT s.pid, s.datid, d.datname, |