0001-Expose-progress-for-the-vacuuming-indexes-phase-of-a.patch

application/octet-stream

Filename: 0001-Expose-progress-for-the-vacuuming-indexes-phase-of-a.patch
Type: application/octet-stream
Part: 1
Message: Re: Add index scan progress to pg_stat_progress_vacuum

Patch

Format: format-patch
Series: patch 0001
Subject: Expose progress for the "vacuuming indexes" phase of a VACUUM operation.
File+
doc/src/sgml/monitoring.sgml 108 2
src/backend/access/gin/ginvacuum.c 4 0
src/backend/access/gist/gistvacuum.c 4 0
src/backend/access/hash/hash.c 2 0
src/backend/access/heap/vacuumlazy.c 18 1
src/backend/access/nbtree/nbtree.c 2 0
src/backend/access/spgist/spgvacuum.c 4 0
src/backend/catalog/system_views.sql 15 2
src/backend/commands/vacuumparallel.c 18 4
src/include/commands/progress.h 12 7
src/test/regress/expected/rules.out 18 2
From 61c5dd12727c94491131a53e15566c475b5d47f2 Mon Sep 17 00:00:00 2001
From: "Imseih (AWS), Sami" <simseih@amazon.com>
Date: Mon, 10 Jan 2022 04:13:03 +0000
Subject: [PATCH 1/1] Expose progress for the "vacuuming indexes" phase of a
 VACUUM operation.

Author: Sami Imseih, based on suggestions by Nathan Bossart, Peter Geoghegan and Masahiko Sawada
Reviewed by: Nathan Bossart, Justin Pryzby
Discussion: https://www.postgresql.org/message-id/5478DFCD-2333-401A-B2F0-0D186AB09228%40amazon.com
---
 doc/src/sgml/monitoring.sgml          | 110 +++++++++++++++++++++++++-
 src/backend/access/gin/ginvacuum.c    |   4 +
 src/backend/access/gist/gistvacuum.c  |   4 +
 src/backend/access/hash/hash.c        |   2 +
 src/backend/access/heap/vacuumlazy.c  |  19 ++++-
 src/backend/access/nbtree/nbtree.c    |   2 +
 src/backend/access/spgist/spgvacuum.c |   4 +
 src/backend/catalog/system_views.sql  |  17 +++-
 src/backend/commands/vacuumparallel.c |  22 +++++-
 src/include/commands/progress.h       |  19 +++--
 src/test/regress/expected/rules.out   |  20 ++++-
 11 files changed, 205 insertions(+), 18 deletions(-)

diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 62f2a3332b..e82e2753bf 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -6135,8 +6135,10 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
    Whenever <command>VACUUM</command> is running, the
    <structname>pg_stat_progress_vacuum</structname> view will contain
    one row for each backend (including autovacuum worker processes) that is
-   currently vacuuming.  The tables below describe the information
-   that will be reported and provide information about how to interpret it.
+   currently vacuuming. The <structname>pg_stat_progress_vacuum_index</structname> 
+   view will also contain one row for each backend that is currently vacuuming an index. 
+   The tables below describe the information that will be reported and provide 
+   information about how to interpret it.
    Progress for <command>VACUUM FULL</command> commands is reported via
    <structname>pg_stat_progress_cluster</structname>
    because both <command>VACUUM FULL</command> and <command>CLUSTER</command>
@@ -6269,6 +6271,110 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
        Number of dead tuples collected since the last index vacuum cycle.
       </para></entry>
      </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>num_indexes_to_vacuum</structfield> <type>bigint</type>
+      </para>
+      <para>
+       The number of indexes that will be vacuumed. Only indexes with 
+       <literal>pg_index.indisready</literal> set to "true" will be vacuumed.
+	   Whenever <xref linkend="guc-vacuum-failsafe-age"/> is triggered, index
+       vacuuming will be bypassed.
+      </para></entry>
+     </row>
+    </tbody>
+   </tgroup>
+  </table>
+
+  <table id="pg-stat-progress-vacuum-index-view" xreflabel="pg_stat_progress_vacuum_index">
+   <title><structname>pg_stat_progress_vacuum_index</structname> View</title>
+   <tgroup cols="1">
+    <thead>
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       Column Type
+      </para>
+      <para>
+       Description
+      </para></entry>
+     </row>
+    </thead>
+
+    <tbody>
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>pid</structfield> <type>integer</type>
+      </para>
+      <para>
+       Process ID of backend.
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>datid</structfield> <type>oid</type>
+      </para>
+      <para>
+       OID of the database to which this backend is connected.
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>datname</structfield> <type>name</type>
+      </para>
+      <para>
+       Name of the database to which this backend is connected.
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>relid</structfield> <type>oid</type>
+      </para>
+      <para>
+       OID of the table being vacuumed.
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>leader_pid</structfield> <type>bigint</type>
+      </para>
+      <para>
+       Process ID of the parallel group leader. This field is <literal>NULL</literal> 
+       if this process is a parallel group leader or the
+       <literal>vacuuming indexes</literal> phase is not performed in parallel.
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>indexrelid</structfield> <type>bigint</type>
+      </para>
+      <para>
+       OID of the index being vacuumed.
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>index_ordinal_position</structfield> <type>bigint</type>
+      </para>
+      <para>
+       The order in which the index is being vacuumed. Indexes are vacuumed by OID in ascending order.
+      </para></entry>
+     </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>index_tuples_removed</structfield> <type>bigint</type>
+      </para>
+      <para>
+       The number of tuple indexes removed during the <literal>vacuuming indexes</literal> phase of <literal>VACUUM</literal>.
+      </para></entry>
+     </row>
     </tbody>
    </tgroup>
   </table>
diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c
index b4fa5f6bf8..b7beeab751 100644
--- a/src/backend/access/gin/ginvacuum.c
+++ b/src/backend/access/gin/ginvacuum.c
@@ -17,8 +17,10 @@
 #include "access/gin_private.h"
 #include "access/ginxlog.h"
 #include "access/xloginsert.h"
+#include "commands/progress.h"
 #include "commands/vacuum.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "storage/indexfsm.h"
 #include "storage/lmgr.h"
@@ -60,6 +62,8 @@ ginVacuumItemPointers(GinVacuumState *gvs, ItemPointerData *items,
 		if (gvs->callback(items + i, gvs->callback_state))
 		{
 			gvs->result->tuples_removed += 1;
+			pgstat_progress_update_param(PROGRESS_VACUUM_DEAD_TUPLES_VACUUMED, gvs->result->tuples_removed);
+
 			if (!tmpitems)
 			{
 				/*
diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c
index aac4afab8f..d288edc8cd 100644
--- a/src/backend/access/gist/gistvacuum.c
+++ b/src/backend/access/gist/gistvacuum.c
@@ -17,9 +17,11 @@
 #include "access/genam.h"
 #include "access/gist_private.h"
 #include "access/transam.h"
+#include "commands/progress.h"
 #include "commands/vacuum.h"
 #include "lib/integerset.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "storage/indexfsm.h"
 #include "storage/lmgr.h"
 #include "utils/memutils.h"
@@ -375,6 +377,8 @@ restart:
 			END_CRIT_SECTION();
 
 			vstate->stats->tuples_removed += ntodelete;
+			pgstat_progress_update_param(PROGRESS_VACUUM_DEAD_TUPLES_VACUUMED, vstate->stats->tuples_removed);
+
 			/* must recompute maxoff */
 			maxoff = PageGetMaxOffsetNumber(page);
 		}
diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c
index d48c8a4549..c1df85bce8 100644
--- a/src/backend/access/hash/hash.c
+++ b/src/backend/access/hash/hash.c
@@ -631,6 +631,8 @@ loop_top:
 	stats->estimated_count = false;
 	stats->num_index_tuples = num_index_tuples;
 	stats->tuples_removed += tuples_removed;
+	pgstat_progress_update_param(PROGRESS_VACUUM_DEAD_TUPLES_VACUUMED, stats->tuples_removed);
+
 	/* hashvacuumcleanup will fill in num_pages */
 
 	return stats;
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 5e4a5d0d82..c73d2013a0 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -343,6 +343,7 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
 
 	pgstat_progress_start_command(PROGRESS_COMMAND_VACUUM,
 								  RelationGetRelid(rel));
+	pgstat_progress_update_param(PROGRESS_VACUUM_LEADER_PID, -1);
 
 	vacuum_set_xid_limits(rel,
 						  params->freeze_min_age,
@@ -447,6 +448,9 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
 	errcallback.previous = error_context_stack;
 	error_context_stack = &errcallback;
 
+	/* Advertise the number of indexes to vacuum if we are not in failsafe mode */
+	if (!lazy_check_wraparound_failsafe(vacrel))
+		pgstat_progress_update_param(PROGRESS_VACUUM_TOTAL_INDEX_VACUUM, vacrel->nindexes);
 	/*
 	 * Call lazy_scan_heap to perform all required heap pruning, index
 	 * vacuuming, and heap vacuuming (plus related processing)
@@ -2038,6 +2042,7 @@ static bool
 lazy_vacuum_all_indexes(LVRelState *vacrel)
 {
 	bool		allindexes = true;
+	PGRUsage	ru0;
 
 	Assert(vacrel->nindexes > 0);
 	Assert(vacrel->do_index_vacuuming);
@@ -2056,6 +2061,8 @@ lazy_vacuum_all_indexes(LVRelState *vacrel)
 	pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
 								 PROGRESS_VACUUM_PHASE_VACUUM_INDEX);
 
+	pg_rusage_init(&ru0);
+
 	if (!ParallelVacuumIsActive(vacrel))
 	{
 		for (int idx = 0; idx < vacrel->nindexes; idx++)
@@ -2063,14 +2070,22 @@ lazy_vacuum_all_indexes(LVRelState *vacrel)
 			Relation	indrel = vacrel->indrels[idx];
 			IndexBulkDeleteResult *istat = vacrel->indstats[idx];
 
+			/* Advertise the index that is being vacuumed and the vacuum order of the index */
+			pgstat_progress_update_param(PROGRESS_VACUUM_CURRENT_INDRELID, indrel->rd_id);
+			pgstat_progress_update_param(PROGRESS_VACUUM_INDEX_ORDINAL, idx + 1);
+
 			vacrel->indstats[idx] =
 				lazy_vacuum_one_index(indrel, istat, vacrel->old_live_tuples,
 									  vacrel);
 
+			/* Advertise that we are done vacuuming the index */
+			pgstat_progress_update_param(PROGRESS_VACUUM_CURRENT_INDRELID, 0);
+
 			if (lazy_check_wraparound_failsafe(vacrel))
 			{
 				/* Wraparound emergency -- end current index scan */
 				allindexes = false;
+				pgstat_progress_update_param(PROGRESS_VACUUM_TOTAL_INDEX_VACUUM, 0);
 				break;
 			}
 		}
@@ -2085,8 +2100,10 @@ lazy_vacuum_all_indexes(LVRelState *vacrel)
 		 * Do a postcheck to consider applying wraparound failsafe now.  Note
 		 * that parallel VACUUM only gets the precheck and this postcheck.
 		 */
-		if (lazy_check_wraparound_failsafe(vacrel))
+		if (lazy_check_wraparound_failsafe(vacrel)) {
 			allindexes = false;
+			pgstat_progress_update_param(PROGRESS_VACUUM_TOTAL_INDEX_VACUUM, 0);
+		}
 	}
 
 	/*
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index 13024af2fa..27cedf20b9 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -1272,6 +1272,8 @@ backtrack:
 								nupdatable);
 
 			stats->tuples_removed += nhtidsdead;
+			pgstat_progress_update_param(PROGRESS_VACUUM_DEAD_TUPLES_VACUUMED, stats->tuples_removed);
+
 			/* must recompute maxoff */
 			maxoff = PageGetMaxOffsetNumber(page);
 
diff --git a/src/backend/access/spgist/spgvacuum.c b/src/backend/access/spgist/spgvacuum.c
index 0049630532..9753eb8090 100644
--- a/src/backend/access/spgist/spgvacuum.c
+++ b/src/backend/access/spgist/spgvacuum.c
@@ -21,8 +21,10 @@
 #include "access/transam.h"
 #include "access/xloginsert.h"
 #include "catalog/storage_xlog.h"
+#include "commands/progress.h"
 #include "commands/vacuum.h"
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "storage/bufmgr.h"
 #include "storage/indexfsm.h"
 #include "storage/lmgr.h"
@@ -160,6 +162,7 @@ vacuumLeafPage(spgBulkDeleteState *bds, Relation index, Buffer buffer,
 				bds->stats->tuples_removed += 1;
 				deletable[i] = true;
 				nDeletable++;
+				pgstat_progress_update_param(PROGRESS_VACUUM_DEAD_TUPLES_VACUUMED, bds->stats->tuples_removed);
 			}
 			else
 			{
@@ -430,6 +433,7 @@ vacuumLeafRoot(spgBulkDeleteState *bds, Relation index, Buffer buffer)
 				bds->stats->tuples_removed += 1;
 				toDelete[xlrec.nDelete] = i;
 				xlrec.nDelete++;
+				pgstat_progress_update_param(PROGRESS_VACUUM_DEAD_TUPLES_VACUUMED, bds->stats->tuples_removed);
 			}
 			else
 			{
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 701ff38f76..5bba12f678 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1124,9 +1124,22 @@ CREATE VIEW pg_stat_progress_vacuum AS
                       END AS phase,
         S.param2 AS heap_blks_total, S.param3 AS heap_blks_scanned,
         S.param4 AS heap_blks_vacuumed, S.param5 AS index_vacuum_count,
-        S.param6 AS max_dead_tuples, S.param7 AS num_dead_tuples
+        S.param6 AS max_dead_tuples, S.param7 AS num_dead_tuples,
+        S.param11 AS num_indexes_to_vacuum
     FROM pg_stat_get_progress_info('VACUUM') AS S
-        LEFT JOIN pg_database D ON S.datid = D.oid;
+        LEFT JOIN pg_database D ON S.datid = D.oid
+    WHERE (S.pid = S.param9 OR S.param9 = -1); -- show vacuum progress for the leader PID only
+
+CREATE VIEW pg_stat_progress_vacuum_index AS
+    SELECT
+        S.pid AS pid, S.datid AS datid, D.datname AS datname,
+        S.relid AS relid,
+        CASE S.param9 WHEN -1 THEN NULL ELSE S.param9 END AS leader_pid,
+        S.param8 AS indexrelid,
+        S.param10 AS index_ordinal_position, S.param12 AS index_tuples_removed
+    FROM pg_stat_get_progress_info('VACUUM') AS S
+        LEFT JOIN pg_database D ON S.datid = D.oid
+    WHERE S.param8 > 0; -- show vacuum progress for a PID that has advertised an index relid
 
 CREATE VIEW pg_stat_progress_cluster AS
     SELECT
diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c
index 53a59da2d6..6bb4a37d96 100644
--- a/src/backend/commands/vacuumparallel.c
+++ b/src/backend/commands/vacuumparallel.c
@@ -29,6 +29,7 @@
 #include "access/amapi.h"
 #include "access/table.h"
 #include "catalog/index.h"
+#include "commands/progress.h"
 #include "commands/vacuum.h"
 #include "optimizer/paths.h"
 #include "pgstat.h"
@@ -206,7 +207,7 @@ static void parallel_vacuum_process_all_indexes(ParallelVacuumState *pvs, int nu
 static void parallel_vacuum_process_safe_indexes(ParallelVacuumState *pvs);
 static void parallel_vacuum_process_unsafe_indexes(ParallelVacuumState *pvs);
 static void parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel,
-											  PVIndStats *indstats);
+											  PVIndStats *indstats, int ordinal_position);
 static bool parallel_vacuum_index_is_parallel_safe(Relation indrel, int num_index_scans,
 												   bool vacuum);
 static void parallel_vacuum_error_callback(void *arg);
@@ -754,7 +755,7 @@ parallel_vacuum_process_safe_indexes(ParallelVacuumState *pvs)
 			continue;
 
 		/* Do vacuum or cleanup of the index */
-		parallel_vacuum_process_one_index(pvs, pvs->indrels[idx], indstats);
+		parallel_vacuum_process_one_index(pvs, pvs->indrels[idx], indstats, idx + 1);
 	}
 
 	/*
@@ -795,7 +796,7 @@ parallel_vacuum_process_unsafe_indexes(ParallelVacuumState *pvs)
 			continue;
 
 		/* Do vacuum or cleanup of the index */
-		parallel_vacuum_process_one_index(pvs, pvs->indrels[i], indstats);
+		parallel_vacuum_process_one_index(pvs, pvs->indrels[i], indstats, i + 1);
 	}
 
 	/*
@@ -814,7 +815,7 @@ parallel_vacuum_process_unsafe_indexes(ParallelVacuumState *pvs)
  */
 static void
 parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel,
-								  PVIndStats *indstats)
+								  PVIndStats *indstats, int ordinal_position)
 {
 	IndexBulkDeleteResult *istat = NULL;
 	IndexBulkDeleteResult *istat_res;
@@ -842,7 +843,14 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel,
 	switch (indstats->status)
 	{
 		case PARALLEL_INDVAC_STATUS_NEED_BULKDELETE:
+			/* Advertise the index that is being vacuumed and the vacuum order of the index */
+			pgstat_progress_update_param(PROGRESS_VACUUM_CURRENT_INDRELID, indrel->rd_id);
+			pgstat_progress_update_param(PROGRESS_VACUUM_INDEX_ORDINAL, ordinal_position);
+
 			istat_res = vac_bulkdel_one_index(&ivinfo, istat, pvs->dead_items);
+
+			/* Advertise that we are done vacuuming the index */
+			pgstat_progress_update_param(PROGRESS_VACUUM_CURRENT_INDRELID, 0);
 			break;
 		case PARALLEL_INDVAC_STATUS_NEED_CLEANUP:
 			istat_res = vac_cleanup_one_index(&ivinfo, istat);
@@ -942,6 +950,7 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
 	int			nindexes;
 	char	   *sharedquery;
 	ErrorContextCallback errcallback;
+	PGPROC     *leader = MyProc->lockGroupLeader;
 
 	/*
 	 * A parallel vacuum worker must have only PROC_IN_VACUUM flag since we
@@ -965,6 +974,10 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
 	 */
 	rel = table_open(shared->relid, ShareUpdateExclusiveLock);
 
+	pgstat_progress_start_command(PROGRESS_COMMAND_VACUUM,
+								  RelationGetRelid(rel));
+	pgstat_progress_update_param(PROGRESS_VACUUM_LEADER_PID, leader->pid);
+
 	/*
 	 * Open all indexes. indrels are sorted in order by OID, which should be
 	 * matched to the leader's one.
@@ -1035,6 +1048,7 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
 	vac_close_indexes(nindexes, indrels, RowExclusiveLock);
 	table_close(rel, ShareUpdateExclusiveLock);
 	FreeAccessStrategy(pvs.bstrategy);
+	pgstat_progress_end_command();
 }
 
 /*
diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h
index a28938caf4..fe3971f075 100644
--- a/src/include/commands/progress.h
+++ b/src/include/commands/progress.h
@@ -18,13 +18,18 @@
 #define PROGRESS_H
 
 /* Progress parameters for (lazy) vacuum */
-#define PROGRESS_VACUUM_PHASE					0
-#define PROGRESS_VACUUM_TOTAL_HEAP_BLKS			1
-#define PROGRESS_VACUUM_HEAP_BLKS_SCANNED		2
-#define PROGRESS_VACUUM_HEAP_BLKS_VACUUMED		3
-#define PROGRESS_VACUUM_NUM_INDEX_VACUUMS		4
-#define PROGRESS_VACUUM_MAX_DEAD_TUPLES			5
-#define PROGRESS_VACUUM_NUM_DEAD_TUPLES			6
+#define PROGRESS_VACUUM_PHASE					 0
+#define PROGRESS_VACUUM_TOTAL_HEAP_BLKS			 1
+#define PROGRESS_VACUUM_HEAP_BLKS_SCANNED		 2
+#define PROGRESS_VACUUM_HEAP_BLKS_VACUUMED		 3
+#define PROGRESS_VACUUM_NUM_INDEX_VACUUMS		 4
+#define PROGRESS_VACUUM_MAX_DEAD_TUPLES			 5
+#define PROGRESS_VACUUM_NUM_DEAD_TUPLES			 6
+#define PROGRESS_VACUUM_CURRENT_INDRELID         7
+#define PROGRESS_VACUUM_LEADER_PID               8
+#define PROGRESS_VACUUM_INDEX_ORDINAL			 9
+#define PROGRESS_VACUUM_TOTAL_INDEX_VACUUM		 10
+#define PROGRESS_VACUUM_DEAD_TUPLES_VACUUMED	 11
 
 /* Phases of vacuum (as advertised via PROGRESS_VACUUM_PHASE) */
 #define PROGRESS_VACUUM_PHASE_SCAN_HEAP			1
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index b58b062b10..a00e0db28c 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2024,9 +2024,25 @@ pg_stat_progress_vacuum| SELECT s.pid,
     s.param4 AS heap_blks_vacuumed,
     s.param5 AS index_vacuum_count,
     s.param6 AS max_dead_tuples,
-    s.param7 AS num_dead_tuples
+    s.param7 AS num_dead_tuples,
+    s.param11 AS num_indexes_to_vacuum
    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)));
+     LEFT JOIN pg_database d ON ((s.datid = d.oid)))
+  WHERE ((s.pid = s.param9) OR (s.param9 = '-1'::integer));
+pg_stat_progress_vacuum_index| SELECT s.pid,
+    s.datid,
+    d.datname,
+    s.relid,
+        CASE s.param9
+            WHEN '-1'::integer THEN NULL::bigint
+            ELSE s.param9
+        END AS leader_pid,
+    s.param8 AS indexrelid,
+    s.param10 AS index_ordinal_position,
+    s.param12 AS index_tuples_removed
+   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)))
+  WHERE (s.param8 > 0);
 pg_stat_replication| SELECT s.pid,
     s.usesysid,
     u.rolname AS usename,
-- 
2.32.0