Add started_by column to pg_stat_progress_analyze view.
authorMasahiko Sawada <msawada@postgresql.org>
Tue, 9 Dec 2025 19:23:45 +0000 (11:23 -0800)
committerMasahiko Sawada <msawada@postgresql.org>
Tue, 9 Dec 2025 19:23:45 +0000 (11:23 -0800)
The new column, started_by, indicates the initiator of the
analyze ('manual' or 'autovacuum'), helping users and monitoring tools
to better understand ANALYZE behavior.

Bump catalog version.

Author: Shinya Kato <shinya11.kato@gmail.com>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Reviewed-by: Sami Imseih <samimseih@gmail.com>
Reviewed-by: Yu Wang <wangyu_runtime@163.com>
Discussion: https://postgr.es/m/CAA5RZ0suoicwxFeK_eDkUrzF7s0BVTaE7M%2BehCpYcCk5wiECpw%40mail.gmail.com

doc/src/sgml/monitoring.sgml
src/backend/catalog/system_views.sql
src/backend/commands/analyze.c
src/include/catalog/catversion.h
src/include/commands/progress.h
src/test/regress/expected/rules.out

index cc2b590e7a23512569fa50a47bfcec9e76f917c5..817fd9f4ca7af0868c9f30403fc3043e7e9a9d44 100644 (file)
@@ -5770,6 +5770,31 @@ FROM pg_stat_get_backend_idset() AS backendid;
        zero).
       </para></entry>
      </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>started_by</structfield> <type>text</type>
+      </para>
+      <para>
+       Shows what caused the current <command>ANALYZE</command> operation to be
+       started. Possible values are:
+       <itemizedlist>
+        <listitem>
+         <para>
+          <literal>manual</literal>: The analyze was started by an explicit
+          <command>ANALYZE</command>, or by <command>VACUUM</command> with
+          the <option>ANALYZE</option> option.
+         </para>
+        </listitem>
+        <listitem>
+         <para>
+          <literal>autovacuum</literal>: The analyze was started by an
+          autovacuum worker.
+         </para>
+        </listitem>
+       </itemizedlist>
+      </para></entry>
+     </row>
     </tbody>
    </tgroup>
   </table>
index e929c3547d5d9597fef991cea7daf03b88d14a2f..0a0f95f6bb9fe62d87e395b2df1d73f6e1745e3c 100644 (file)
@@ -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;
 
index 25089fae3e006686db255f5d953d78c8d4e00bb5..b2429170679a871ee811ea063d7c563c544a7d64 100644 (file)
@@ -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
index 3bd0f8499eb4e8c6d84cdacb9e55e6b8bcb308cc..d1b2e1cd2d1346cdf47fb94153a27b472732594c 100644 (file)
@@ -57,6 +57,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 202512092
+#define CATALOG_VERSION_NO 202512093
 
 #endif
index 45ed6e6e1ccadcbeb8fbab1b53256c9ea82396b2..9dc63a5a5bd5048589a89b9d7b333c18a214583d 100644 (file)
@@ -60,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
 #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
index 1e5bb3cafcc9d17f004b5ac25357b9c3978c1ae5..4286c266e17f39dca9e66a356165793061b0a30f 100644 (file)
@@ -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,