{
        bool            allindexes = true;
        double          old_live_tuples = vacrel->rel->rd_rel->reltuples;
+       const int       progress_start_index[] = {
+               PROGRESS_VACUUM_PHASE,
+               PROGRESS_VACUUM_INDEXES_TOTAL
+       };
+       const int       progress_end_index[] = {
+               PROGRESS_VACUUM_INDEXES_TOTAL,
+               PROGRESS_VACUUM_INDEXES_PROCESSED,
+               PROGRESS_VACUUM_NUM_INDEX_VACUUMS
+       };
+       int64           progress_start_val[2];
+       int64           progress_end_val[3];
 
        Assert(vacrel->nindexes > 0);
        Assert(vacrel->do_index_vacuuming);
                return false;
        }
 
-       /* Report that we are now vacuuming indexes */
-       pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
-                                                                PROGRESS_VACUUM_PHASE_VACUUM_INDEX);
+       /*
+        * Report that we are now vacuuming indexes and the number of indexes to
+        * vacuum.
+        */
+       progress_start_val[0] = PROGRESS_VACUUM_PHASE_VACUUM_INDEX;
+       progress_start_val[1] = vacrel->nindexes;
+       pgstat_progress_update_multi_param(2, progress_start_index, progress_start_val);
 
        if (!ParallelVacuumIsActive(vacrel))
        {
                                                                                                                  old_live_tuples,
                                                                                                                  vacrel);
 
+                       /* Report the number of indexes vacuumed */
+                       pgstat_progress_update_param(PROGRESS_VACUUM_INDEXES_PROCESSED,
+                                                                                idx + 1);
+
                        if (lazy_check_wraparound_failsafe(vacrel))
                        {
                                /* Wraparound emergency -- end current index scan */
        Assert(allindexes || VacuumFailsafeActive);
 
        /*
-        * Increase and report the number of index scans.
+        * Increase and report the number of index scans.  Also, we reset
+        * PROGRESS_VACUUM_INDEXES_TOTAL and PROGRESS_VACUUM_INDEXES_PROCESSED.
         *
         * We deliberately include the case where we started a round of bulk
         * deletes that we weren't able to finish due to the failsafe triggering.
         */
        vacrel->num_index_scans++;
-       pgstat_progress_update_param(PROGRESS_VACUUM_NUM_INDEX_VACUUMS,
-                                                                vacrel->num_index_scans);
+       progress_end_val[0] = 0;
+       progress_end_val[1] = 0;
+       progress_end_val[2] = vacrel->num_index_scans;
+       pgstat_progress_update_multi_param(3, progress_end_index, progress_end_val);
 
        return allindexes;
 }
 
        if (unlikely(vacuum_xid_failsafe_check(&vacrel->cutoffs)))
        {
+               const int       progress_index[] = {
+                       PROGRESS_VACUUM_INDEXES_TOTAL,
+                       PROGRESS_VACUUM_INDEXES_PROCESSED
+               };
+               int64           progress_val[2] = {0, 0};
+
                VacuumFailsafeActive = true;
 
                /*
                vacrel->do_index_cleanup = false;
                vacrel->do_rel_truncate = false;
 
+               /* Reset the progress counters */
+               pgstat_progress_update_multi_param(2, progress_index, progress_val);
+
                ereport(WARNING,
                                (errmsg("bypassing nonessential maintenance of table \"%s.%s.%s\" as a failsafe after %d index scans",
                                                vacrel->dbname, vacrel->relnamespace, vacrel->relname,
 {
        double          reltuples = vacrel->new_rel_tuples;
        bool            estimated_count = vacrel->scanned_pages < vacrel->rel_pages;
+       const int       progress_start_index[] = {
+               PROGRESS_VACUUM_PHASE,
+               PROGRESS_VACUUM_INDEXES_TOTAL
+       };
+       const int       progress_end_index[] = {
+               PROGRESS_VACUUM_INDEXES_TOTAL,
+               PROGRESS_VACUUM_INDEXES_PROCESSED
+       };
+       int64           progress_start_val[2];
+       int64           progress_end_val[2] = {0, 0};
 
        Assert(vacrel->do_index_cleanup);
        Assert(vacrel->nindexes > 0);
 
-       /* Report that we are now cleaning up indexes */
-       pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
-                                                                PROGRESS_VACUUM_PHASE_INDEX_CLEANUP);
+       /*
+        * Report that we are now cleaning up indexes and the number of indexes to
+        * cleanup.
+        */
+       progress_start_val[0] = PROGRESS_VACUUM_PHASE_INDEX_CLEANUP;
+       progress_start_val[1] = vacrel->nindexes;
+       pgstat_progress_update_multi_param(2, progress_start_index, progress_start_val);
 
        if (!ParallelVacuumIsActive(vacrel))
        {
                        vacrel->indstats[idx] =
                                lazy_cleanup_one_index(indrel, istat, reltuples,
                                                                           estimated_count, vacrel);
+
+                       /* Report the number of indexes cleaned up */
+                       pgstat_progress_update_param(PROGRESS_VACUUM_INDEXES_PROCESSED,
+                                                                                idx + 1);
                }
        }
        else
                                                                                        vacrel->num_index_scans,
                                                                                        estimated_count);
        }
+
+       /* Reset the progress counters */
+       pgstat_progress_update_multi_param(2, progress_end_index, progress_end_val);
 }
 
 /*
 
     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.param8 AS indexes_total,
+    s.param9 AS indexes_processed
    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,