diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml
index f4f0433ef6f0..ab0cb02a3d23 100644
--- a/doc/src/sgml/maintenance.sgml
+++ b/doc/src/sgml/maintenance.sgml
@@ -1018,8 +1018,11 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu
see . However, if the autovacuum
is running to prevent transaction ID wraparound (i.e., the autovacuum query
name in the pg_stat_activity view ends with
- (to prevent wraparound)), the autovacuum is not
- automatically interrupted.
+ (to prevent wraparound) or the
+ autovacuum_wraparound value in the
+ started_by column in the
+ pg_stat_progress_vacuum view), the autovacuum is
+ not automatically interrupted.
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index d2dd5e283658..d487a3a5c4e7 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -5770,6 +5770,31 @@ FROM pg_stat_get_backend_idset() AS backendid;
zero).
+
+
+
+ started_bytext
+
+
+ Shows what caused the current ANALYZE operation to be
+ started. Possible values are:
+
+
+
+ manual: The analyze was started by an explicit
+ ANALYZE or VACUUM with the
+ option.
+
+
+
+
+ autovacuum: The analyze was started by an
+ autovacuum worker.
+
+
+
+
+
@@ -6710,6 +6735,81 @@ FROM pg_stat_get_backend_idset() AS backendid;
stale.
+
+
+
+ modetext
+
+
+ The mode in which the current VACUUM operation is
+ running. See for details of each
+ mode. Possible values are:
+
+
+
+ normal: The operation is performing a standard
+ vacuum. It is neither required to run in aggressive mode nor operating
+ in failsafe mode.
+
+
+
+
+ aggressive: The operation is running an aggressive
+ vacuum, which must scan every page that is not marked all-frozen.
+ The parameters and
+ determine when a
+ table requires aggressive vacuuming.
+
+
+
+
+ failsafe: The vacuum has entered failsafe mode,
+ in which it performs only the minimum work necessary to avoid
+ transaction ID or multixact ID wraparound failure.
+ The parameters and
+ determine when the
+ vacuum enters failsafe mode. The vacuum may start in this mode or
+ switch to it while running; the value of the
+ mode column may transition from another
+ mode to failsafe during the operation.
+
+
+
+
+
+
+
+
+ started_bytext
+
+
+ Shows what caused the current VACUUM operation to be
+ started. Possible values are:
+
+
+
+ manual: The vacuum was started by an explicit
+ VACUUM command.
+
+
+
+
+ autovacuum: The vacuum was started by an autovacuum
+ worker. Vacuums run by autovacuum workers may be interrupted due to
+ lock conflicts.
+
+
+
+
+ autovacuum_wraparound: The vacuum was started by an
+ autovacuum worker to prevent transaction ID or multixact ID
+ wraparound. Vacuums run for wraparound protection are not interrupted
+ due to lock conflicts.
+
+
+
+
+
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 65bb0568a867..cc5b03eb7cea 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -664,6 +664,14 @@ heap_vacuum_rel(Relation rel, const VacuumParams params,
pgstat_progress_start_command(PROGRESS_COMMAND_VACUUM,
RelationGetRelid(rel));
+ if (AmAutoVacuumWorkerProcess())
+ pgstat_progress_update_param(PROGRESS_VACUUM_STARTED_BY,
+ params.is_wraparound
+ ? PROGRESS_VACUUM_STARTED_BY_AUTOVACUUM_WRAPAROUND
+ : PROGRESS_VACUUM_STARTED_BY_AUTOVACUUM);
+ else
+ pgstat_progress_update_param(PROGRESS_VACUUM_STARTED_BY,
+ PROGRESS_VACUUM_STARTED_BY_MANUAL);
/*
* Setup error traceback support for ereport() first. The idea is to set
@@ -820,6 +828,12 @@ heap_vacuum_rel(Relation rel, const VacuumParams params,
*/
heap_vacuum_eager_scan_setup(vacrel, params);
+ /* Report the vacuum mode: 'normal' or 'aggressive' */
+ pgstat_progress_update_param(PROGRESS_VACUUM_MODE,
+ vacrel->aggressive
+ ? PROGRESS_VACUUM_MODE_AGGRESSIVE
+ : PROGRESS_VACUUM_MODE_NORMAL);
+
if (verbose)
{
if (vacrel->aggressive)
@@ -3001,9 +3015,10 @@ lazy_check_wraparound_failsafe(LVRelState *vacrel)
{
const int progress_index[] = {
PROGRESS_VACUUM_INDEXES_TOTAL,
- PROGRESS_VACUUM_INDEXES_PROCESSED
+ PROGRESS_VACUUM_INDEXES_PROCESSED,
+ PROGRESS_VACUUM_MODE
};
- int64 progress_val[2] = {0, 0};
+ int64 progress_val[3] = {0, 0, PROGRESS_VACUUM_MODE_FAILSAFE};
VacuumFailsafeActive = true;
@@ -3019,8 +3034,8 @@ lazy_check_wraparound_failsafe(LVRelState *vacrel)
vacrel->do_index_cleanup = false;
vacrel->do_rel_truncate = false;
- /* Reset the progress counters */
- pgstat_progress_update_multi_param(2, progress_index, progress_val);
+ /* Reset the progress counters and set the failsafe mode */
+ pgstat_progress_update_multi_param(3, progress_index, progress_val);
ereport(WARNING,
(errmsg("bypassing nonessential maintenance of table \"%s.%s.%s\" as a failsafe after %d index scans",
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 48af8ee90a6d..0a0f95f6bb9f 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1247,7 +1247,10 @@ CREATE VIEW pg_stat_progress_analyze AS
S.param6 AS child_tables_total,
S.param7 AS child_tables_done,
CAST(S.param8 AS oid) AS current_child_table_relid,
- S.param9 / 1000000::double precision AS delay_time
+ S.param9 / 1000000::double precision AS delay_time,
+ CASE S.param10 WHEN 1 THEN 'manual'
+ WHEN 2 THEN 'autovacuum'
+ ELSE NULL END AS started_by
FROM pg_stat_get_progress_info('ANALYZE') AS S
LEFT JOIN pg_database D ON S.datid = D.oid;
@@ -1268,7 +1271,15 @@ CREATE VIEW pg_stat_progress_vacuum AS
S.param6 AS max_dead_tuple_bytes, S.param7 AS dead_tuple_bytes,
S.param8 AS num_dead_item_ids, S.param9 AS indexes_total,
S.param10 AS indexes_processed,
- S.param11 / 1000000::double precision AS delay_time
+ S.param11 / 1000000::double precision AS delay_time,
+ CASE S.param12 WHEN 1 THEN 'normal'
+ WHEN 2 THEN 'aggressive'
+ WHEN 3 THEN 'failsafe'
+ ELSE NULL END AS mode,
+ CASE S.param13 WHEN 1 THEN 'manual'
+ WHEN 2 THEN 'autovacuum'
+ WHEN 3 THEN 'autovacuum_wraparound'
+ ELSE NULL END AS started_by
FROM pg_stat_get_progress_info('VACUUM') AS S
LEFT JOIN pg_database D ON S.datid = D.oid;
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 25089fae3e00..b2429170679a 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -239,6 +239,12 @@ analyze_rel(Oid relid, RangeVar *relation,
*/
pgstat_progress_start_command(PROGRESS_COMMAND_ANALYZE,
RelationGetRelid(onerel));
+ if (AmAutoVacuumWorkerProcess())
+ pgstat_progress_update_param(PROGRESS_ANALYZE_STARTED_BY,
+ PROGRESS_ANALYZE_STARTED_BY_AUTOVACUUM);
+ else
+ pgstat_progress_update_param(PROGRESS_ANALYZE_STARTED_BY,
+ PROGRESS_ANALYZE_STARTED_BY_MANUAL);
/*
* Do the normal non-recursive ANALYZE. We can skip this for partitioned
diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h
index 1cde4bd9bcf1..9dc63a5a5bd5 100644
--- a/src/include/commands/progress.h
+++ b/src/include/commands/progress.h
@@ -29,6 +29,8 @@
#define PROGRESS_VACUUM_INDEXES_TOTAL 8
#define PROGRESS_VACUUM_INDEXES_PROCESSED 9
#define PROGRESS_VACUUM_DELAY_TIME 10
+#define PROGRESS_VACUUM_MODE 11
+#define PROGRESS_VACUUM_STARTED_BY 12
/* Phases of vacuum (as advertised via PROGRESS_VACUUM_PHASE) */
#define PROGRESS_VACUUM_PHASE_SCAN_HEAP 1
@@ -38,6 +40,16 @@
#define PROGRESS_VACUUM_PHASE_TRUNCATE 5
#define PROGRESS_VACUUM_PHASE_FINAL_CLEANUP 6
+/* Modes of vacuum (as advertised via PROGRESS_VACUUM_MODE) */
+#define PROGRESS_VACUUM_MODE_NORMAL 1
+#define PROGRESS_VACUUM_MODE_AGGRESSIVE 2
+#define PROGRESS_VACUUM_MODE_FAILSAFE 3
+
+/* Reasons for vacuum (as advertised via PROGRESS_VACUUM_STARTED_BY) */
+#define PROGRESS_VACUUM_STARTED_BY_MANUAL 1
+#define PROGRESS_VACUUM_STARTED_BY_AUTOVACUUM 2
+#define PROGRESS_VACUUM_STARTED_BY_AUTOVACUUM_WRAPAROUND 3
+
/* Progress parameters for analyze */
#define PROGRESS_ANALYZE_PHASE 0
#define PROGRESS_ANALYZE_BLOCKS_TOTAL 1
@@ -48,6 +60,7 @@
#define PROGRESS_ANALYZE_CHILD_TABLES_DONE 6
#define PROGRESS_ANALYZE_CURRENT_CHILD_TABLE_RELID 7
#define PROGRESS_ANALYZE_DELAY_TIME 8
+#define PROGRESS_ANALYZE_STARTED_BY 9
/* Phases of analyze (as advertised via PROGRESS_ANALYZE_PHASE) */
#define PROGRESS_ANALYZE_PHASE_ACQUIRE_SAMPLE_ROWS 1
@@ -56,6 +69,10 @@
#define PROGRESS_ANALYZE_PHASE_COMPUTE_EXT_STATS 4
#define PROGRESS_ANALYZE_PHASE_FINALIZE_ANALYZE 5
+/* Reasons for analyze (as advertised via PROGRESS_ANALYZE_STARTED_BY) */
+#define PROGRESS_ANALYZE_STARTED_BY_MANUAL 1
+#define PROGRESS_ANALYZE_STARTED_BY_AUTOVACUUM 2
+
/* Progress parameters for cluster */
#define PROGRESS_CLUSTER_COMMAND 0
#define PROGRESS_CLUSTER_PHASE 1
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 85d795dbd63b..4286c266e17f 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1969,7 +1969,12 @@ pg_stat_progress_analyze| SELECT s.pid,
s.param6 AS child_tables_total,
s.param7 AS child_tables_done,
(s.param8)::oid AS current_child_table_relid,
- ((s.param9)::double precision / (1000000)::double precision) AS delay_time
+ ((s.param9)::double precision / (1000000)::double precision) AS delay_time,
+ CASE s.param10
+ WHEN 1 THEN 'manual'::text
+ WHEN 2 THEN 'autovacuum'::text
+ ELSE NULL::text
+ END AS started_by
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_basebackup| SELECT pid,
@@ -2105,7 +2110,19 @@ pg_stat_progress_vacuum| SELECT s.pid,
s.param8 AS num_dead_item_ids,
s.param9 AS indexes_total,
s.param10 AS indexes_processed,
- ((s.param11)::double precision / (1000000)::double precision) AS delay_time
+ ((s.param11)::double precision / (1000000)::double precision) AS delay_time,
+ CASE s.param12
+ WHEN 1 THEN 'normal'::text
+ WHEN 2 THEN 'aggressive'::text
+ WHEN 3 THEN 'failsafe'::text
+ ELSE NULL::text
+ END AS mode,
+ CASE s.param13
+ WHEN 1 THEN 'manual'::text
+ WHEN 2 THEN 'autovacuum'::text
+ WHEN 3 THEN 'autovacuum_wraparound'::text
+ ELSE NULL::text
+ END AS started_by
FROM (pg_stat_get_progress_info('VACUUM'::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_recovery_prefetch| SELECT stats_reset,