v20-0001-Add-2-new-columns-to-pg_stat_progress_vacuum.-Th.patch
application/octet-stream
Filename: v20-0001-Add-2-new-columns-to-pg_stat_progress_vacuum.-Th.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v20-0001
Subject: Report index vacuum progress.
| File | + | − |
|---|---|---|
| contrib/bloom/blvacuum.c | 4 | 0 |
| doc/src/sgml/monitoring.sgml | 26 | 0 |
| src/backend/access/gin/ginvacuum.c | 6 | 0 |
| src/backend/access/gist/gistvacuum.c | 4 | 0 |
| src/backend/access/hash/hash.c | 6 | 0 |
| src/backend/access/heap/vacuumlazy.c | 28 | 2 |
| src/backend/access/nbtree/nbtree.c | 2 | 0 |
| src/backend/access/spgist/spgvacuum.c | 3 | 0 |
| src/backend/catalog/index.c | 2 | 0 |
| src/backend/catalog/system_views.sql | 2 | 1 |
| src/backend/commands/analyze.c | 1 | 0 |
| src/backend/commands/vacuumparallel.c | 72 | 2 |
| src/backend/utils/activity/wait_event.c | 3 | 0 |
| src/include/access/genam.h | 4 | 1 |
| src/include/commands/progress.h | 2 | 0 |
| src/include/commands/vacuum.h | 7 | 0 |
| src/include/utils/wait_event.h | 1 | 0 |
| src/test/regress/expected/rules.out | 3 | 1 |
From 4336a7fe6bd9d554bbca4c87001b5d6b753b7aa0 Mon Sep 17 00:00:00 2001
From: EC2 Default User <ec2-user@ip-172-31-94-175.ec2.internal>
Date: Wed, 4 Jan 2023 17:06:09 +0000
Subject: [PATCH 1/1] Report index vacuum progress.
Add 2 new columns to pg_stat_progress_vacuum.
The columns are ndexes_total as the total indexes to be vacuumed or cleaned and
indexes_processed as the number of indexes vacuumed or cleaned up so far.
Author: Sami Imseih, based on suggestions by Nathan Bossart, Peter Geoghegan and Masahiko Sawada
Reviewed by: Nathan Bossart, Masahiko Sawada
Discussion: https://www.postgresql.org/message-id/flat/5478DFCD-2333-401A-B2F0-0D186AB09228@amazon.com
---
contrib/bloom/blvacuum.c | 4 ++
doc/src/sgml/monitoring.sgml | 26 +++++++++
src/backend/access/gin/ginvacuum.c | 6 ++
src/backend/access/gist/gistvacuum.c | 4 ++
src/backend/access/hash/hash.c | 6 ++
src/backend/access/heap/vacuumlazy.c | 30 +++++++++-
src/backend/access/nbtree/nbtree.c | 2 +
src/backend/access/spgist/spgvacuum.c | 3 +
src/backend/catalog/index.c | 2 +
src/backend/catalog/system_views.sql | 3 +-
src/backend/commands/analyze.c | 1 +
src/backend/commands/vacuumparallel.c | 74 ++++++++++++++++++++++++-
src/backend/utils/activity/wait_event.c | 3 +
src/include/access/genam.h | 5 +-
src/include/commands/progress.h | 2 +
src/include/commands/vacuum.h | 7 +++
src/include/utils/wait_event.h | 1 +
src/test/regress/expected/rules.out | 4 +-
18 files changed, 176 insertions(+), 7 deletions(-)
diff --git a/contrib/bloom/blvacuum.c b/contrib/bloom/blvacuum.c
index 2340d49e00..731c16782d 100644
--- a/contrib/bloom/blvacuum.c
+++ b/contrib/bloom/blvacuum.c
@@ -62,6 +62,8 @@ blbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
*itupEnd;
vacuum_delay_point();
+ if (info->report_parallel_progress && (blkno % REPORT_PARALLEL_VACUUM_EVERY_PAGES) == 0)
+ parallel_vacuum_update_progress(info->parallel_vacuum_state);
buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno,
RBM_NORMAL, info->strategy);
@@ -192,6 +194,8 @@ blvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
Page page;
vacuum_delay_point();
+ if (info->report_parallel_progress && (blkno % REPORT_PARALLEL_VACUUM_EVERY_PAGES) == 0)
+ parallel_vacuum_update_progress(info->parallel_vacuum_state);
buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno,
RBM_NORMAL, info->strategy);
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 5bcba0fdec..df468d4424 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1767,6 +1767,10 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
<entry><literal>ParallelFinish</literal></entry>
<entry>Waiting for parallel workers to finish computing.</entry>
</row>
+ <row>
+ <entry><literal>ParallelVacuumFinish</literal></entry>
+ <entry>Waiting for parallel vacuum workers to finish index vacuum.</entry>
+ </row>
<row>
<entry><literal>ProcArrayGroupUpdate</literal></entry>
<entry>Waiting for the group leader to clear the transaction ID at
@@ -6842,6 +6846,28 @@ FROM pg_stat_get_backend_idset() AS backendid;
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>indexes_total</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of indexes that will be vacuumed. This value will be
+ <literal>0</literal> if there are no indexes to vacuum, <literal>INDEX_CLEANUP</literal>
+ is set to <literal>OFF</literal>, or vacuum failsafe is triggered.
+ See <xref linkend="guc-vacuum-failsafe-age"/>
+ for more on vacuum failsafe.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indexes_completed</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of indexes vacuumed in the current vacuum cycle.
+ </para></entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c
index e5d310d836..195065290a 100644
--- a/src/backend/access/gin/ginvacuum.c
+++ b/src/backend/access/gin/ginvacuum.c
@@ -665,6 +665,9 @@ ginbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
vacuum_delay_point();
+ if (info->report_parallel_progress && (blkno % REPORT_PARALLEL_VACUUM_EVERY_PAGES) == 0)
+ parallel_vacuum_update_progress(info->parallel_vacuum_state);
+
for (i = 0; i < nRoot; i++)
{
ginVacuumPostingTree(&gvs, rootOfPostingTree[i]);
@@ -751,6 +754,9 @@ ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
vacuum_delay_point();
+ if (info->report_parallel_progress && (blkno % REPORT_PARALLEL_VACUUM_EVERY_PAGES) == 0)
+ parallel_vacuum_update_progress(info->parallel_vacuum_state);
+
buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno,
RBM_NORMAL, info->strategy);
LockBuffer(buffer, GIN_SHARE);
diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c
index 3f60d3274d..8783c766ce 100644
--- a/src/backend/access/gist/gistvacuum.c
+++ b/src/backend/access/gist/gistvacuum.c
@@ -223,7 +223,11 @@ gistvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
break;
/* Iterate over pages, then loop back to recheck length */
for (; blkno < num_pages; blkno++)
+ {
gistvacuumpage(&vstate, blkno, blkno);
+ if (info->report_parallel_progress && (blkno % REPORT_PARALLEL_VACUUM_EVERY_PAGES) == 0)
+ parallel_vacuum_update_progress(info->parallel_vacuum_state);
+ }
}
/*
diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c
index eb258337d6..2426dcd968 100644
--- a/src/backend/access/hash/hash.c
+++ b/src/backend/access/hash/hash.c
@@ -505,6 +505,12 @@ loop_top:
blkno = bucket_blkno;
+ /*
+ * For hash indexes, we report parallel vacuum progress
+ * for every bucket.
+ */
+ if (info->report_parallel_progress)
+ parallel_vacuum_update_progress(info->parallel_vacuum_state);
/*
* We need to acquire a cleanup lock on the primary bucket page to out
* wait concurrent scans before deleting the dead tuples.
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index a42e881da3..e65f43fbe9 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -413,6 +413,10 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
Assert(params->index_cleanup == VACOPTVALUE_AUTO);
}
+ /* Report the number of indexes to vacuum, if we are told to cleanup indexes */
+ if (vacrel->do_index_cleanup)
+ pgstat_progress_update_param(PROGRESS_VACUUM_INDEX_TOTAL, vacrel->nindexes);
+
/* Initialize page counters explicitly (be tidy) */
vacrel->scanned_pages = 0;
vacrel->removed_pages = 0;
@@ -2321,6 +2325,10 @@ lazy_vacuum_all_indexes(LVRelState *vacrel)
old_live_tuples,
vacrel);
+ /* Done vacuuming an index -- increment the indexes completed */
+ pgstat_progress_update_param(PROGRESS_VACUUM_INDEX_COMPLETED,
+ idx + 1);
+
if (lazy_check_wraparound_failsafe(vacrel))
{
/* Wraparound emergency -- end current index scan */
@@ -2355,11 +2363,14 @@ lazy_vacuum_all_indexes(LVRelState *vacrel)
Assert(allindexes || vacrel->failsafe_active);
/*
- * Increase and report the number of index scans.
+ * Reset and report zero as the number of indexes scanned.
+ * Also, increase and report the number of index
+ * scans.
*
* 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.
*/
+ pgstat_progress_update_param(PROGRESS_VACUUM_INDEX_COMPLETED, 0);
vacrel->num_index_scans++;
pgstat_progress_update_param(PROGRESS_VACUUM_NUM_INDEX_VACUUMS,
vacrel->num_index_scans);
@@ -2609,10 +2620,17 @@ lazy_check_wraparound_failsafe(LVRelState *vacrel)
{
vacrel->failsafe_active = true;
- /* Disable index vacuuming, index cleanup, and heap rel truncation */
+ /*
+ * Disable index vacuuming, index cleanup, and heap rel truncation.
+ *
+ * Also, report that we are no longer tracking
+ * index vacuum/cleanup.
+ */
vacrel->do_index_vacuuming = false;
vacrel->do_index_cleanup = false;
vacrel->do_rel_truncate = false;
+ pgstat_progress_update_param(PROGRESS_VACUUM_INDEX_TOTAL, 0);
+ pgstat_progress_update_param(PROGRESS_VACUUM_INDEX_COMPLETED, 0);
ereport(WARNING,
(errmsg("bypassing nonessential maintenance of table \"%s.%s.%s\" as a failsafe after %d index scans",
@@ -2658,6 +2676,10 @@ lazy_cleanup_all_indexes(LVRelState *vacrel)
vacrel->indstats[idx] =
lazy_cleanup_one_index(indrel, istat, reltuples,
estimated_count, vacrel);
+
+ /* Done cleaning an index -- increment the indexes completed */
+ pgstat_progress_update_param(PROGRESS_VACUUM_INDEX_COMPLETED,
+ idx + 1);
}
}
else
@@ -2692,10 +2714,12 @@ lazy_vacuum_one_index(Relation indrel, IndexBulkDeleteResult *istat,
ivinfo.index = indrel;
ivinfo.analyze_only = false;
ivinfo.report_progress = false;
+ ivinfo.report_parallel_progress = false;
ivinfo.estimated_count = true;
ivinfo.message_level = DEBUG2;
ivinfo.num_heap_tuples = reltuples;
ivinfo.strategy = vacrel->bstrategy;
+ ivinfo.parallel_vacuum_state = NULL;
/*
* Update error traceback information.
@@ -2740,11 +2764,13 @@ lazy_cleanup_one_index(Relation indrel, IndexBulkDeleteResult *istat,
ivinfo.index = indrel;
ivinfo.analyze_only = false;
ivinfo.report_progress = false;
+ ivinfo.report_parallel_progress = false;
ivinfo.estimated_count = estimated_count;
ivinfo.message_level = DEBUG2;
ivinfo.num_heap_tuples = reltuples;
ivinfo.strategy = vacrel->bstrategy;
+ ivinfo.parallel_vacuum_state = NULL;
/*
* Update error traceback information.
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index 1cc88da032..eb69409c6a 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -998,6 +998,8 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
if (info->report_progress)
pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_DONE,
scanblkno);
+ if (info->report_parallel_progress && (scanblkno % REPORT_PARALLEL_VACUUM_EVERY_PAGES) == 0)
+ parallel_vacuum_update_progress(info->parallel_vacuum_state);
}
}
diff --git a/src/backend/access/spgist/spgvacuum.c b/src/backend/access/spgist/spgvacuum.c
index 3adb18f2d8..b28036a830 100644
--- a/src/backend/access/spgist/spgvacuum.c
+++ b/src/backend/access/spgist/spgvacuum.c
@@ -843,6 +843,9 @@ spgvacuumscan(spgBulkDeleteState *bds)
/* empty the pending-list after each page */
if (bds->pendingList != NULL)
spgprocesspending(bds);
+ /* report parallel vacuum progress */
+ if (bds->info->report_parallel_progress && (blkno % REPORT_PARALLEL_VACUUM_EVERY_PAGES) == 0)
+ parallel_vacuum_update_progress(bds->info->parallel_vacuum_state);
}
}
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index e6579f2979..c734b2d4ce 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3348,10 +3348,12 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot)
ivinfo.index = indexRelation;
ivinfo.analyze_only = false;
ivinfo.report_progress = true;
+ ivinfo.report_parallel_progress = false;
ivinfo.estimated_count = true;
ivinfo.message_level = DEBUG2;
ivinfo.num_heap_tuples = heapRelation->rd_rel->reltuples;
ivinfo.strategy = NULL;
+ ivinfo.parallel_vacuum_state = NULL;
/*
* Encode TIDs as int8 values for the sort, rather than directly sorting
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 447c9b970f..0ab864185f 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1165,7 +1165,8 @@ 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.param8 AS indexes_total, S.param9 AS indexes_completed
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 c86e690980..84c1d2f3c7 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -712,6 +712,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
ivinfo.message_level = elevel;
ivinfo.num_heap_tuples = onerel->rd_rel->reltuples;
ivinfo.strategy = vac_strategy;
+ ivinfo.parallel_vacuum_state = NULL;
stats = index_vacuum_cleanup(&ivinfo, NULL);
diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c
index bcd40c80a1..8e2be7d15b 100644
--- a/src/backend/commands/vacuumparallel.c
+++ b/src/backend/commands/vacuumparallel.c
@@ -30,6 +30,7 @@
#include "access/table.h"
#include "access/xact.h"
#include "catalog/index.h"
+#include "commands/progress.h"
#include "commands/vacuum.h"
#include "optimizer/paths.h"
#include "pgstat.h"
@@ -103,6 +104,17 @@ typedef struct PVShared
/* Counter for vacuuming and cleanup */
pg_atomic_uint32 idx;
+
+ /*
+ * Counter for vacuuming and cleanup progress reporting.
+ * This value is used to report index vacuum/cleanup progress
+ * in parallel_vacuum_progress_report. We keep this
+ * counter to avoid having to loop through
+ * ParallelVacuumState->indstats to determine the number
+ * of indexes completed.
+ */
+ pg_atomic_uint32 nindexes_completed;
+
} PVShared;
/* Status used during parallel index vacuum or cleanup */
@@ -213,6 +225,7 @@ static void parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation
static bool parallel_vacuum_index_is_parallel_safe(Relation indrel, int num_index_scans,
bool vacuum);
static void parallel_vacuum_error_callback(void *arg);
+static void parallel_vacuum_wait_to_finish(ParallelVacuumState *pvs);
/*
* Try to enter parallel mode and create a parallel context. Then initialize
@@ -364,6 +377,7 @@ parallel_vacuum_init(Relation rel, Relation *indrels, int nindexes,
pg_atomic_init_u32(&(shared->cost_balance), 0);
pg_atomic_init_u32(&(shared->active_nworkers), 0);
pg_atomic_init_u32(&(shared->idx), 0);
+ pg_atomic_init_u32(&(shared->nindexes_completed), 0);
shm_toc_insert(pcxt->toc, PARALLEL_VACUUM_KEY_SHARED, shared);
pvs->shared = shared;
@@ -618,8 +632,9 @@ parallel_vacuum_process_all_indexes(ParallelVacuumState *pvs, int num_index_scan
vacuum));
}
- /* Reset the parallel index processing counter */
+ /* Reset the parallel index processing and progress counters */
pg_atomic_write_u32(&(pvs->shared->idx), 0);
+ pg_atomic_write_u32(&(pvs->shared->nindexes_completed), 0);
/* Setup the shared cost-based vacuum delay and launch workers */
if (nworkers > 0)
@@ -688,7 +703,13 @@ parallel_vacuum_process_all_indexes(ParallelVacuumState *pvs, int num_index_scan
*/
if (nworkers > 0)
{
- /* Wait for all vacuum workers to finish */
+ /*
+ * Wait for all indexes to be vacuumed while
+ * updating the parallel vacuum index progress,
+ * and then wait for all workers to finish.
+ */
+ parallel_vacuum_wait_to_finish(pvs);
+
WaitForParallelWorkersToFinish(pvs->pcxt);
for (int i = 0; i < pvs->pcxt->nworkers_launched; i++)
@@ -839,9 +860,13 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel,
ivinfo.num_heap_tuples = pvs->shared->reltuples;
ivinfo.strategy = pvs->bstrategy;
+ /* Only the leader should report parallel vacuum progress */
+ ivinfo.report_parallel_progress = !IsParallelWorker();
/* Update error traceback information */
pvs->indname = pstrdup(RelationGetRelationName(indrel));
pvs->status = indstats->status;
+ /* Pass ParallelVacuumState to IndexVacuumInfo for progress reporting */
+ ivinfo.parallel_vacuum_state = pvs;
switch (indstats->status)
{
@@ -888,6 +913,12 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel,
pvs->status = PARALLEL_INDVAC_STATUS_COMPLETED;
pfree(pvs->indname);
pvs->indname = NULL;
+
+ /* Update the number of indexes completed */
+ pg_atomic_add_fetch_u32(&(pvs->shared->nindexes_completed), 1);
+
+ if (ivinfo.report_parallel_progress)
+ parallel_vacuum_update_progress(pvs);
}
/*
@@ -1072,3 +1103,42 @@ parallel_vacuum_error_callback(void *arg)
return;
}
}
+
+/*
+ * Read pvs->shared->nindexes_completed and report the number of indexes
+ * vacuumed so far. This function is called periodically
+ * by index AMs as well as parallel_vacuum_process_one_index.
+ *
+ * Note: This function should be called by the leader process only,
+ * and it's up to the caller to ensure this.
+ */
+void
+parallel_vacuum_update_progress(ParallelVacuumState *pvs)
+{
+ Assert(!IsParallelWorker());
+
+ if (pvs)
+ pgstat_progress_update_param(PROGRESS_VACUUM_INDEX_COMPLETED,
+ pg_atomic_read_u32(&pvs->shared->nindexes_completed));
+}
+
+/*
+ * Waiting for all indexes to be vacuumed while updating the
+ * parallel index vacuum progress.
+ */
+void
+parallel_vacuum_wait_to_finish(ParallelVacuumState *pvs)
+{
+ Assert(!IsParallelWorker());
+
+ while (pg_atomic_read_u32(&pvs->shared->nindexes_completed) < pvs->nindexes)
+ {
+ CHECK_FOR_INTERRUPTS();
+
+ parallel_vacuum_update_progress(pvs);
+
+ (void) WaitLatch(MyLatch, WL_TIMEOUT | WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 1000L,
+ WAIT_EVENT_PARALLEL_VACUUM_FINISH);
+ ResetLatch(MyLatch);
+ }
+}
diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c
index f9574e800f..1a06428f3c 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -415,6 +415,9 @@ pgstat_get_wait_ipc(WaitEventIPC w)
case WAIT_EVENT_PARALLEL_FINISH:
event_name = "ParallelFinish";
break;
+ case WAIT_EVENT_PARALLEL_VACUUM_FINISH:
+ event_name = "ParallelVacuumFinish";
+ break;
case WAIT_EVENT_PROCARRAY_GROUP_UPDATE:
event_name = "ProcArrayGroupUpdate";
break;
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index 83dbee0fe6..6e0f12cef0 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -21,8 +21,9 @@
#include "utils/relcache.h"
#include "utils/snapshot.h"
-/* We don't want this file to depend on execnodes.h. */
+/* We don't want this file to depend on execnodes.h or vacuum.h. */
struct IndexInfo;
+struct ParallelVacuumState;
/*
* Struct for statistics returned by ambuild
@@ -46,10 +47,12 @@ typedef struct IndexVacuumInfo
Relation index; /* the index being vacuumed */
bool analyze_only; /* ANALYZE (without any actual vacuum) */
bool report_progress; /* emit progress.h status reports */
+ bool report_parallel_progress; /* emit progress.h status reports for parallel vacuum */
bool estimated_count; /* num_heap_tuples is an estimate */
int message_level; /* ereport level for progress messages */
double num_heap_tuples; /* tuples remaining in heap */
BufferAccessStrategy strategy; /* access strategy for reads */
+ struct ParallelVacuumState *parallel_vacuum_state; /* access parallel vacuum state for progress reporting */
} IndexVacuumInfo;
/*
diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h
index e5add41352..6b8b609a4f 100644
--- a/src/include/commands/progress.h
+++ b/src/include/commands/progress.h
@@ -25,6 +25,8 @@
#define PROGRESS_VACUUM_NUM_INDEX_VACUUMS 4
#define PROGRESS_VACUUM_MAX_DEAD_TUPLES 5
#define PROGRESS_VACUUM_NUM_DEAD_TUPLES 6
+#define PROGRESS_VACUUM_INDEX_TOTAL 7
+#define PROGRESS_VACUUM_INDEX_COMPLETED 8
/* Phases of vacuum (as advertised via PROGRESS_VACUUM_PHASE) */
#define PROGRESS_VACUUM_PHASE_SCAN_HEAP 1
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 5efb942368..84a2216119 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -64,6 +64,12 @@
/* value for checking vacuum flags */
#define VACUUM_OPTION_MAX_VALID_VALUE ((1 << 3) - 1)
+/*
+ * Parallel Index vacuum progress is reported every 1GB of blocks
+ * scanned.
+ */
+#define REPORT_PARALLEL_VACUUM_EVERY_PAGES ((BlockNumber) (((uint64) 1024 * 1024 * 1024) / BLCKSZ))
+
/* Abstract type for parallel vacuum state */
typedef struct ParallelVacuumState ParallelVacuumState;
@@ -368,5 +374,6 @@ extern bool std_typanalyze(VacAttrStats *stats);
extern double anl_random_fract(void);
extern double anl_init_selection_state(int n);
extern double anl_get_next_S(double t, int n, double *stateptr);
+extern void parallel_vacuum_update_progress(ParallelVacuumState *pvs);
#endif /* VACUUM_H */
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index f53254ad1f..46930fe7f5 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -114,6 +114,7 @@ typedef enum
WAIT_EVENT_PARALLEL_BITMAP_SCAN,
WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN,
WAIT_EVENT_PARALLEL_FINISH,
+ WAIT_EVENT_PARALLEL_VACUUM_FINISH,
WAIT_EVENT_PROCARRAY_GROUP_UPDATE,
WAIT_EVENT_PROC_SIGNAL_BARRIER,
WAIT_EVENT_PROMOTE,
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index fb9f936d43..df6f230715 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2021,7 +2021,9 @@ 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.param8 AS indexes_total,
+ s.param9 AS indexes_completed
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 s.stats_reset,
--
2.38.1