v1-0001-Add-mode-to-pg_stat_progress_vacuum.patch
application/x-patch
Filename: v1-0001-Add-mode-to-pg_stat_progress_vacuum.patch
Type: application/x-patch
Part: 0
From e06ac211652a9706d5e6511083f6777260e041b5 Mon Sep 17 00:00:00 2001
From: Shinya Kato <shinya11.kato@gmail.com>
Date: Thu, 14 Aug 2025 15:28:39 +0900
Subject: [PATCH v1] Add mode to pg_stat_progress_vacuum
This commit enhances the pg_stat_progress_vacuum view by adding a mode
column, which provides visibility into the nature of the running vacuum
process.
The mode can be one of the following:
- normal: A standard, user-initiated VACUUM or a regular autovacuum run.
- anti-wraparound: An autovacuum run for anti-wraparound purposes.
- failsafe: A failsafe vacuum activated to prevent transaction ID
wraparound.
This allows administrators to better understand the context and urgency
of vacuum operations.
---
doc/src/sgml/monitoring.sgml | 32 ++++++++++++++++++++++++++++
src/backend/access/heap/vacuumlazy.c | 13 +++++++----
src/backend/catalog/system_views.sql | 6 +++++-
src/include/commands/progress.h | 6 ++++++
src/test/regress/expected/rules.out | 8 ++++++-
5 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 3f4a27a736e..3ca994f73bb 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -6607,6 +6607,38 @@ FROM pg_stat_get_backend_idset() AS backendid;
stale.
</para></entry>
</row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>mode</structfield> <type>text</type>
+ </para>
+ <para>
+ The mode of the current vacuum operation. Possible values are:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>normal</literal>: A standard vacuum operation, including
+ user-initiated <command>VACUUM</command> command and autovacuum runs
+ not triggered for anti-wraparound purposes.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>anti-wraparound</literal>: An autovacuum run specifically to
+ prevent transaction ID or multixact ID wraparound.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>failsafe</literal>: A vacuum operation that entered failsafe
+ mode when the system was at risk of transaction ID or multixact ID
+ wraparound (see <xref linkend="guc-vacuum-failsafe-age"/> and
+ <xref linkend="guc-vacuum-multixact-failsafe-age"/>).
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para></entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 14036c27e87..f77dbed7899 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -652,6 +652,10 @@ heap_vacuum_rel(Relation rel, const VacuumParams params,
pgstat_progress_start_command(PROGRESS_COMMAND_VACUUM,
RelationGetRelid(rel));
+ pgstat_progress_update_param(PROGRESS_VACUUM_MODE,
+ params.is_wraparound
+ ? PROGRESS_VACUUM_MODE_ANTI_WRAPAROUND
+ : PROGRESS_VACUUM_MODE_NORMAL);
/*
* Setup error traceback support for ereport() first. The idea is to set
@@ -2957,9 +2961,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;
@@ -2975,8 +2980,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 the 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 1b3c5a55882..685086edd8f 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1248,7 +1248,11 @@ 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 'anti-wraparound'
+ WHEN 3 THEN 'failsafe'
+ END AS mode
FROM pg_stat_get_progress_info('VACUUM') AS S
LEFT JOIN pg_database D ON S.datid = D.oid;
diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h
index 1cde4bd9bcf..73f267a002f 100644
--- a/src/include/commands/progress.h
+++ b/src/include/commands/progress.h
@@ -29,6 +29,7 @@
#define PROGRESS_VACUUM_INDEXES_TOTAL 8
#define PROGRESS_VACUUM_INDEXES_PROCESSED 9
#define PROGRESS_VACUUM_DELAY_TIME 10
+#define PROGRESS_VACUUM_MODE 11
/* Phases of vacuum (as advertised via PROGRESS_VACUUM_PHASE) */
#define PROGRESS_VACUUM_PHASE_SCAN_HEAP 1
@@ -38,6 +39,11 @@
#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_ANTI_WRAPAROUND 2
+#define PROGRESS_VACUUM_MODE_FAILSAFE 3
+
/* Progress parameters for analyze */
#define PROGRESS_ANALYZE_PHASE 0
#define PROGRESS_ANALYZE_BLOCKS_TOTAL 1
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 35e8aad7701..60b5d87a130 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2094,7 +2094,13 @@ 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 'anti-wraparound'::text
+ WHEN 3 THEN 'failsafe'::text
+ ELSE NULL::text
+ END AS mode
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,
--
2.47.3