pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Imseih (AWS), Sami <simseih@amazon.com>
To: Masahiko Sawada <sawada.mshk@gmail.com>
To: Nathan Bossart <nathandbossart@gmail.com>
Cc: Peter Geoghegan <pg@bowt.ie>
Cc: Bossart, Nathan <bossartn@amazon.com>
Cc: Justin Pryzby <pryzby@telsasoft.com>
Cc: pgsql-hackers@postgresql.org <pgsql-hackers@postgresql.org>
Subject: Re: Add index scan progress to pg_stat_progress_vacuum
Date: Mon, 14 Mar 2022 22:21:50 +0000
Message-ID: <4F14170D-AF67-4FDF-9EB0-2A1F8EA14899@amazon.com> (raw)
In-Reply-To: <78C9A1C5-8593-47F8-8717-42C554A724E9@amazon.com>
References: <28F7536A-3E62-4A6B-9705-A2377A2D03AE@amazon.com>
	<CAH2-Wzmk7fJuUNVX85AR3eS7MUGait7LrbhP8_8Y74W=m61Hnw@mail.gmail.com>
	<20220225195253.GA663211@nathanxps13>
	<B741F5D1-2B29-4CD6-8938-E6265AB45476@amazon.com>
	<CAD21AoA4kNdG6Qi8Qr4vFpvrGKd9MqjVPLUVZMEoBWHdCqfu9Q@mail.gmail.com>
	<F5F2CD8C-49D4-4B9A-983F-E3FF0E8CF048@amazon.com>
	<CAD21AoBW6SMJ96CNoMeu+f_BR4jmatPcfVA016FdD2hkLDsaTA@mail.gmail.com>
	<D4BBFE30-AB76-49E1-9A47-5A2851CCCB9F@amazon.com>
	<CAD21AoDf4pf89i7fgzrHDdJueNHLm4x92xHjcDeYaV+pdhem-Q@mail.gmail.com>
	<99A5CBE8-EC10-42AA-ABB4-4C812EEFD294@amazon.com>
	<20220310005237.GA307769@nathanxps13>
	<DD7EEE19-EFFB-481C-A6EC-26B1E0356F7A@amazon.com>
	<CAD21AoD13LQ4+suYVWCyp07PHgoHVmAPZwc8neNdkTFVsSi-ww@mail.gmail.com>
	<78C9A1C5-8593-47F8-8717-42C554A724E9@amazon.com>

Attaching a v8 due to naming convention fixes and one slight change in where index_processed is set after all indexes are vacuumed.

s/indexes_completed/indexes_processed/

--
Sami Imseih
Amazon Web Services





Attachments: download all (4 files, .tar.gz)

v8-0001-Add-infrastructure-for-parallel-progress-reportin.patch (application/octet-stream, 9.9K) download From e67da55a69f03da0725b68add27feabb0a08dbe5 Mon Sep 17 00:00:00 2001 From: "Sami Imseih (AWS)" <simseih@amazon.com> Date: Mon, 14 Mar 2022 21:32:44 +0000 Subject: [PATCH v8 1/4] Add infrastructure for parallel progress reporting Infrastructure to allow a parallel worker to report progress. In a PARALLEL command, the workers and leader can report progress using a new pgstat_progress API. The progress is maintaned in a shared memory hash table for which progress values are aggregated for all processes involved in the command. pg_stat_get_progress_info reads from the shared memory hash to report the aggregated data to the caller. 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/flat/5478DFCD-2333-401A-B2F0-0D186AB09228%40amazon.com --- src/backend/storage/ipc/ipci.c | 3 + src/backend/storage/lmgr/lwlocknames.txt | 1 + src/backend/utils/activity/backend_progress.c | 166 ++++++++++++++++++ src/backend/utils/adt/pgstatfuncs.c | 10 +- src/include/utils/backend_progress.h | 12 +- 5 files changed, 188 insertions(+), 4 deletions(-) diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index cd4ebe2fc5..ccb9262b97 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -24,6 +24,7 @@ #include "access/twophase.h" #include "access/xlogrecovery.h" #include "commands/async.h" +#include "commands/progress.h" #include "miscadmin.h" #include "pgstat.h" #include "postmaster/autovacuum.h" @@ -145,6 +146,7 @@ CalculateShmemSize(int *num_semaphores) size = add_size(size, BTreeShmemSize()); size = add_size(size, SyncScanShmemSize()); size = add_size(size, AsyncShmemSize()); + size = add_size(size, ProgressParallelShmemSize()); #ifdef EXEC_BACKEND size = add_size(size, ShmemBackendArraySize()); #endif @@ -296,6 +298,7 @@ CreateSharedMemoryAndSemaphores(void) BTreeShmemInit(); SyncScanShmemInit(); AsyncShmemInit(); + ProgressParallelShmemInit(); #ifdef EXEC_BACKEND diff --git a/src/backend/storage/lmgr/lwlocknames.txt b/src/backend/storage/lmgr/lwlocknames.txt index 6c7cf6c295..4212dea7f3 100644 --- a/src/backend/storage/lmgr/lwlocknames.txt +++ b/src/backend/storage/lmgr/lwlocknames.txt @@ -53,3 +53,4 @@ XactTruncationLock 44 # 45 was XactTruncationLock until removal of BackendRandomLock WrapLimitsVacuumLock 46 NotifyQueueTailLock 47 +ProgressParallelLock 48 diff --git a/src/backend/utils/activity/backend_progress.c b/src/backend/utils/activity/backend_progress.c index f29199725b..de69aaa8ad 100644 --- a/src/backend/utils/activity/backend_progress.c +++ b/src/backend/utils/activity/backend_progress.c @@ -10,10 +10,30 @@ */ #include "postgres.h" +#include "commands/progress.h" #include "port/atomics.h" /* for memory barriers */ +#include "storage/ipc.h" +#include "storage/lmgr.h" +#include "storage/shmem.h" #include "utils/backend_progress.h" #include "utils/backend_status.h" +/* + * Structs for parallel progress tracking. + * + * The parallel workers and leader report progress + * into a hash entry with a key of the leader pid. + */ +typedef struct ProgressParallelEntry +{ + pid_t leader_pid; + int64 st_progress_param[PGSTAT_NUM_PROGRESS_PARAM]; +} ProgressParallelEntry; + +static HTAB *ProgressParallelHash; + +/* We can only have as many parallel progress entries as max_parallel_workers */ +#define PROGRESS_PARALLEL_NUM_ENTRIES max_worker_processes /*----------- * pgstat_progress_start_command() - @@ -110,3 +130,149 @@ pgstat_progress_end_command(void) beentry->st_progress_command_target = InvalidOid; PGSTAT_END_WRITE_ACTIVITY(beentry); } + +/*----------- + * ProgressParallelShmemInit() - + * + * Initialize the parallel progress hash. + *----------- + */ +void +ProgressParallelShmemInit(void) +{ + HASHCTL info; + + info.keysize = sizeof(pid_t); + info.entrysize = sizeof(ProgressParallelEntry); + + ProgressParallelHash = ShmemInitHash("Parallel Progress hash", + PROGRESS_PARALLEL_NUM_ENTRIES, + PROGRESS_PARALLEL_NUM_ENTRIES, + &info, + HASH_ELEM | HASH_BLOBS); +} + +/*----------- + * ProgressParallelShmemSize() - + * + * Calculate the size of the parallel progress hash. + *----------- + */ +Size +ProgressParallelShmemSize(void) +{ + Size size = 0; + + /* parallel progress hash table */ + size = add_size(size, hash_estimate_size(PROGRESS_PARALLEL_NUM_ENTRIES, + sizeof(ProgressParallelEntry))); + + return size; +} + +/*----------- + * pgstat_progress_update_param_parallel() - + * + * Update the index'th member in then st_progress_param[] of the + * parallel progress hash table. + *----------- + */ +void +pgstat_progress_update_param_parallel(int leader_pid, int index, int64 val) +{ + ProgressParallelEntry *entry; + bool found; + + LWLockAcquire(ProgressParallelLock, LW_EXCLUSIVE); + + entry = (ProgressParallelEntry *) hash_search(ProgressParallelHash, &leader_pid, HASH_ENTER, &found); + + /* + * If the entry is not found, set the value for the index'th member, + * else increment the current value of the index'th member. + */ + if (!found) + entry->st_progress_param[index] = val; + else + entry->st_progress_param[index] += val; + + LWLockRelease(ProgressParallelLock); +} + +/*----------- + * pgstat_progress_end_parallel() - + * + * This removes an entry with from the parallel progress + * hash table. + *----------- + */ +void +pgstat_progress_end_parallel(int leader_pid) +{ + LWLockAcquire(ProgressParallelLock, LW_EXCLUSIVE); + + /* + * Remove from hashtable. It should always be present, + * but don't complain if it's not. + */ + hash_search(ProgressParallelHash, &leader_pid, HASH_REMOVE, NULL); + + LWLockRelease(ProgressParallelLock); +} + +/*----------- + * pgstat_progress_end_parallel_callback() - + * + * PG_ENSURE_ERROR_CLEANUP callback. The caller is responsible + * for ensuring cleanup when invoking pgstat_progress_update_param_parallel. + *----------- + */ +void +pgstat_progress_end_parallel_callback(int code, Datum arg) +{ + pgstat_progress_end_parallel(DatumGetInt32(arg)); +} + +/*----------- + * pgstat_progress_set_parallel() - + * + * This routine is called by pg_stat_get_progress_info + * to update the datum with values from the parallel progress + * hash. + *----------- + */ +void +pgstat_progress_set_parallel(Datum *values) +{ + ProgressParallelEntry *entry; + /* First element of the datum is always the pid */ + int leader_pid = values[0]; + + LWLockAcquire(ProgressParallelLock, LW_SHARED); + + entry = (ProgressParallelEntry *) hash_search(ProgressParallelHash, &leader_pid, HASH_FIND, NULL); + + /* + * If an entry is not found, it is because we looked at a pid that is not involved in a parallel command, + * therefore release the read lock and break. + */ + if (!entry) + { + LWLockRelease(ProgressParallelLock); + return; + } + + for (int i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++) + { + int64 val = entry->st_progress_param[i]; + + /* + * We only care about hash entry members that have been updated by + * parallel workers ( or leader ). This is true if the member's value > 0. + */ + if (val > 0) + values[i + PGSTAT_NUM_PROGRESS_COMMON] = val; + } + + LWLockRelease(ProgressParallelLock); +} diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index eff45b16f2..1856e9c3b6 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -18,6 +18,7 @@ #include "access/xlog.h" #include "catalog/pg_authid.h" #include "catalog/pg_type.h" +#include "commands/progress.h" #include "common/ip.h" #include "funcapi.h" #include "miscadmin.h" @@ -456,7 +457,7 @@ pg_stat_get_backend_idset(PG_FUNCTION_ARGS) Datum pg_stat_get_progress_info(PG_FUNCTION_ARGS) { -#define PG_STAT_GET_PROGRESS_COLS PGSTAT_NUM_PROGRESS_PARAM + 3 +#define PG_STAT_GET_PROGRESS_COLS PGSTAT_NUM_PROGRESS_PARAM + PGSTAT_NUM_PROGRESS_COMMON int num_backends = pgstat_fetch_stat_numbackends(); int curr_backend; char *cmd = text_to_cstring(PG_GETARG_TEXT_PP(0)); @@ -518,15 +519,18 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS) { values[2] = ObjectIdGetDatum(beentry->st_progress_command_target); for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++) - values[i + 3] = Int64GetDatum(beentry->st_progress_param[i]); + values[i + PGSTAT_NUM_PROGRESS_COMMON] = Int64GetDatum(beentry->st_progress_param[i]); } else { nulls[2] = true; for (i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++) - nulls[i + 3] = true; + nulls[i + PGSTAT_NUM_PROGRESS_COMMON] = true; } + /* Before returning the datum, set the fields from parallel progress tracking */ + pgstat_progress_set_parallel(values); + tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); } diff --git a/src/include/utils/backend_progress.h b/src/include/utils/backend_progress.h index 47bf8029b0..936eb97b64 100644 --- a/src/include/utils/backend_progress.h +++ b/src/include/utils/backend_progress.h @@ -31,7 +31,7 @@ typedef enum ProgressCommandType } ProgressCommandType; #define PGSTAT_NUM_PROGRESS_PARAM 20 - +#define PGSTAT_NUM_PROGRESS_COMMON 3 extern void pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid); @@ -40,5 +40,15 @@ extern void pgstat_progress_update_multi_param(int nparam, const int *index, const int64 *val); extern void pgstat_progress_end_command(void); +/* ----------- + * Routines for parallel command progress reporting + * ----------- + */ +extern void ProgressParallelShmemInit(void); +extern Size ProgressParallelShmemSize(void); +extern void pgstat_progress_update_param_parallel(int leader_pid, int index, int64 val); +extern void pgstat_progress_end_parallel(int leader_pid); +extern void pgstat_progress_end_parallel_callback(int code, Datum arg); +extern void pgstat_progress_set_parallel(Datum *values); #endif /* BACKEND_PROGRESS_H */ -- 2.32.0
v8-0002-Show-progress-for-index-vacuums.patch (application/octet-stream, 10.8K) download From 56f9db40e4d1cfa3464198c841bef2a0127563f5 Mon Sep 17 00:00:00 2001 From: "Sami Imseih (AWS)" <simseih@amazon.com> Date: Mon, 14 Mar 2022 21:55:43 +0000 Subject: [PATCH v8 2/4] Show progress for index vacuums Add 2 new columns to pg_stat_progress_vacuum. The columns are indexes_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, Justin Pryzby Discussion: https://www.postgresql.org/message-id/flat/5478DFCD-2333-401A-B2F0-0D186AB09228@amazon.com --- doc/src/sgml/monitoring.sgml | 25 +++++++++++ src/backend/access/heap/vacuumlazy.c | 60 +++++++++++++++++++++++---- src/backend/catalog/system_views.sql | 3 +- src/backend/commands/vacuumparallel.c | 7 ++++ src/include/commands/progress.h | 2 + src/test/regress/expected/rules.out | 4 +- 6 files changed, 92 insertions(+), 9 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 9fb62fec8e..1acc741da9 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -6227,6 +6227,31 @@ 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>indexes_total</structfield> <type>bigint</type> + </para> + <para> + The number of indexes to be processed in the + <literal>vacuuming indexes</literal> + or <literal>cleaning up indexes</literal> phase. It is set to + <literal>0</literal> when there are no indexes to process + or when failsafe is triggered during the vacuum. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>indexes_processed</structfield> <type>bigint</type> + </para> + <para> + The number of indexes already processed in the + <literal>vacuuming indexes</literal> + or <literal>cleaning up indexes</literal> phase. It is set to + <literal>0</literal> when vacuum is not in any of these phases. + </para></entry> + </row> </tbody> </tgroup> </table> diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 87ab7775ae..047a5db494 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -58,6 +58,7 @@ #include "postmaster/autovacuum.h" #include "storage/bufmgr.h" #include "storage/freespace.h" +#include "storage/ipc.h" #include "storage/lmgr.h" #include "tcop/tcopprot.h" #include "utils/lsyscache.h" @@ -2313,9 +2314,13 @@ lazy_vacuum_all_indexes(LVRelState *vacrel) /* Report that we are now vacuuming indexes */ pgstat_progress_update_param(PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_PHASE_VACUUM_INDEX); + /* Advertise the number of indexes we are vacuuming */ + pgstat_progress_update_param(PROGRESS_VACUUM_TOTAL_INDEXES, vacrel->nindexes); if (!ParallelVacuumIsActive(vacrel)) { + int indexes_processed = 1; + for (int idx = 0; idx < vacrel->nindexes; idx++) { Relation indrel = vacrel->indrels[idx]; @@ -2325,6 +2330,8 @@ lazy_vacuum_all_indexes(LVRelState *vacrel) lazy_vacuum_one_index(indrel, istat, vacrel->old_live_tuples, vacrel); + pgstat_progress_update_param(PROGRESS_VACUUM_INDEXES_PROCESSED, indexes_processed++); + if (lazy_check_wraparound_failsafe(vacrel)) { /* Wraparound emergency -- end current index scan */ @@ -2335,9 +2342,21 @@ lazy_vacuum_all_indexes(LVRelState *vacrel) } else { - /* Outsource everything to parallel variant */ - parallel_vacuum_bulkdel_all_indexes(vacrel->pvs, vacrel->old_live_tuples, - vacrel->num_index_scans); + /* + * Outsource everything to parallel variant + * + * To ensure cleanup of the progress worker hash entry, + * wrap parallel_vacuum_bulkdel_all_indexes in a + * PG_ENSURE_ERROR_CLEANUP + * + */ + PG_ENSURE_ERROR_CLEANUP(pgstat_progress_end_parallel_callback, Int32GetDatum(MyProcPid)); + { + parallel_vacuum_bulkdel_all_indexes(vacrel->pvs, vacrel->old_live_tuples, + vacrel->num_index_scans); + } + PG_END_ENSURE_ERROR_CLEANUP(pgstat_progress_end_parallel_callback, Int32GetDatum(MyProcPid)); + pgstat_progress_end_parallel(MyProcPid); /* * Do a postcheck to consider applying wraparound failsafe now. Note @@ -2345,8 +2364,12 @@ lazy_vacuum_all_indexes(LVRelState *vacrel) */ if (lazy_check_wraparound_failsafe(vacrel)) allindexes = false; + } + /* reset index progress */ + pgstat_progress_update_param(PROGRESS_VACUUM_INDEXES_PROCESSED, 0); + /* * We delete all LP_DEAD items from the first heap pass in all indexes on * each call here (except calls where we choose to do the failsafe). This @@ -2628,6 +2651,8 @@ lazy_check_wraparound_failsafe(LVRelState *vacrel) vacrel->do_index_vacuuming = false; vacrel->do_index_cleanup = false; vacrel->do_rel_truncate = false; + pgstat_progress_update_param(PROGRESS_VACUUM_TOTAL_INDEXES, 0); + pgstat_progress_update_param(PROGRESS_VACUUM_INDEXES_PROCESSED, 0); ereport(WARNING, (errmsg("bypassing nonessential maintenance of table \"%s.%s.%s\" as a failsafe after %d index scans", @@ -2664,9 +2689,13 @@ lazy_cleanup_all_indexes(LVRelState *vacrel) /* Report that we are now cleaning up indexes */ pgstat_progress_update_param(PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_PHASE_INDEX_CLEANUP); + /* Advertise the number of indexes we are cleaning up */ + pgstat_progress_update_param(PROGRESS_VACUUM_TOTAL_INDEXES, vacrel->nindexes); if (!ParallelVacuumIsActive(vacrel)) { + int indexes_processed = 1; + for (int idx = 0; idx < vacrel->nindexes; idx++) { Relation indrel = vacrel->indrels[idx]; @@ -2675,15 +2704,32 @@ lazy_cleanup_all_indexes(LVRelState *vacrel) vacrel->indstats[idx] = lazy_cleanup_one_index(indrel, istat, reltuples, estimated_count, vacrel); + + pgstat_progress_update_param(PROGRESS_VACUUM_INDEXES_PROCESSED, indexes_processed++); } } else { - /* Outsource everything to parallel variant */ - parallel_vacuum_cleanup_all_indexes(vacrel->pvs, reltuples, - vacrel->num_index_scans, - estimated_count); + /* + * Outsource everything to parallel variant + * + * To ensure cleanup of the paralle progress hash entry, + * wrap parallel_vacuum_bulkdel_all_indexes in a + * PG_ENSURE_ERROR_CLEANUP + * + */ + PG_ENSURE_ERROR_CLEANUP(pgstat_progress_end_parallel_callback, Int32GetDatum(MyProcPid)); + { + parallel_vacuum_cleanup_all_indexes(vacrel->pvs, reltuples, + vacrel->num_index_scans, + estimated_count); + } + PG_END_ENSURE_ERROR_CLEANUP(pgstat_progress_end_parallel_callback, Int32GetDatum(MyProcPid)); + pgstat_progress_end_parallel(MyProcPid); } + + /* reset index progress */ + pgstat_progress_update_param(PROGRESS_VACUUM_INDEXES_PROCESSED, 0); } /* diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index bb1ac30cd1..35ea25026f 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -1126,7 +1126,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_processed 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/vacuumparallel.c b/src/backend/commands/vacuumparallel.c index 974a29e7a9..f08eb837e7 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" @@ -101,6 +102,9 @@ typedef struct PVShared /* Counter for vacuuming and cleanup */ pg_atomic_uint32 idx; + + /* Leader PID of the vacuum */ + int leader_pid; } PVShared; /* Status used during parallel index vacuum or cleanup */ @@ -357,6 +361,7 @@ parallel_vacuum_init(Relation rel, Relation *indrels, int nindexes, (nindexes_mwm > 0) ? maintenance_work_mem / Min(parallel_workers, nindexes_mwm) : maintenance_work_mem; + shared->leader_pid = MyProcPid; pg_atomic_init_u32(&(shared->cost_balance), 0); pg_atomic_init_u32(&(shared->active_nworkers), 0); @@ -844,9 +849,11 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel, { case PARALLEL_INDVAC_STATUS_NEED_BULKDELETE: istat_res = vac_bulkdel_one_index(&ivinfo, istat, pvs->dead_items); + pgstat_progress_update_param_parallel(pvs->shared->leader_pid, PROGRESS_VACUUM_INDEXES_PROCESSED, 1); break; case PARALLEL_INDVAC_STATUS_NEED_CLEANUP: istat_res = vac_cleanup_one_index(&ivinfo, istat); + pgstat_progress_update_param_parallel(pvs->shared->leader_pid, PROGRESS_VACUUM_INDEXES_PROCESSED, 1); break; default: elog(ERROR, "unexpected parallel vacuum index status %d for index \"%s\"", diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h index a28938caf4..54ee60caad 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_TOTAL_INDEXES 7 +#define PROGRESS_VACUUM_INDEXES_PROCESSED 8 /* 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 ac468568a1..d70a176514 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -2002,7 +2002,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_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_replication| SELECT s.pid, -- 2.32.0
v8-0003-Expose-indexes-being-processed-in-a-VACUUM-operat.patch (application/octet-stream, 16.8K) download From b44359eb937b2f02878ba80fd56b94ef6130ac10 Mon Sep 17 00:00:00 2001 From: "Sami Imseih (AWS)" <simseih@amazon.com> Date: Mon, 14 Mar 2022 22:07:09 +0000 Subject: [PATCH v8 3/4] Expose indexes being processed in a VACUUM operation. A new view called pg_stat_progress_vacuum_index to show the indexrelid being vacuumed or cleaned during a vacuum. The view also shows the number of tuples removed for the index during the vacuuming indexes phase. Author: Sami Imseih, based on suggestions by Nathan Bossart, Peter Geoghegan and Masahiko Sawada Reviewed by: Nathan Bossart, Justin Pryzby --- doc/src/sgml/monitoring.sgml | 108 ++++++++++++++++++++++++++ src/backend/access/gin/ginvacuum.c | 3 + src/backend/access/gist/gistvacuum.c | 3 + src/backend/access/hash/hash.c | 1 + src/backend/access/heap/vacuumlazy.c | 14 ++++ src/backend/access/nbtree/nbtree.c | 1 + src/backend/access/spgist/spgvacuum.c | 4 + src/backend/catalog/system_views.sql | 18 ++++- src/backend/commands/vacuumparallel.c | 12 +++ src/include/commands/progress.h | 3 + src/test/regress/expected/rules.out | 17 +++- 11 files changed, 182 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 1acc741da9..240d2438d5 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -379,6 +379,15 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser </entry> </row> + <row> + <entry><structname>pg_stat_progress_vacuum_index</structname><indexterm><primary>pg_stat_progress_vacuum_index</primary></indexterm></entry> + <entry>One row for each backend (including autovacuum worker processes) that is + currently performing the <literal>vacuuming indexes</literal> or + <literal>cleaning up indexes</literal> phase of the vacuum, showing current progress. + See <xref linkend='vacuum-progress-reporting'/>. + </entry> + </row> + <row> <entry><structname>pg_stat_progress_cluster</structname><indexterm><primary>pg_stat_progress_cluster</primary></indexterm></entry> <entry>One row for each backend running @@ -6256,6 +6265,105 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, </tgroup> </table> + <indexterm> + <primary>pg_stat_progress_vacuum_index</primary> + </indexterm> + + <para> + Whenever <command>VACUUM</command> is running, the + <structname>pg_stat_progress_vacuum_index</structname> view will contain + one row for each backend (including autovacuum worker processes) that is + currently performing the <literal>vacuuming indexes</literal> or + <literal>cleaning up indexes</literal> phase of the vacuum. + </para> + + <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>indexrelid</structfield> <type>oid</type> + </para> + <para> + OID of the index being processed in the ongoing phase of the vacuum. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>leader_pid</structfield> <type>integer</type> + </para> + <para> + Process ID of the parallel vacuum leader, if this process is a + parallel vacuum worker. <literal>NULL</literal> if this process is a + parallel vacuum leader or does not participate in parallel vacuum. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>phase</structfield> <type>text</type> + </para> + <para> + Current processing phase of a vacuum. Only the + <literal>vacuuming indexes</literal> or <literal>cleaning up indexes</literal> + phase will be listed in this view. See <xref linkend="vacuum-phases"/>. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>tuples_removed</structfield> <type>oid</type> + </para> + <para> + The number of index tuples removed by the <literal>vacuuming indexes</literal> phase. + This field is <literal>0</literal> during the <literal>cleaning up indexes</literal> + phase. + </para></entry> + </row> + </tbody> + </tgroup> + </table> + <table id="vacuum-phases"> <title>VACUUM Phases</title> <tgroup cols="2"> diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index b4fa5f6bf8..1d5d003780 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,7 @@ ginVacuumItemPointers(GinVacuumState *gvs, ItemPointerData *items, if (gvs->callback(items + i, gvs->callback_state)) { gvs->result->tuples_removed += 1; + pgstat_progress_update_param(PROGRESS_VACUUM_TUPLES_REMOVED, gvs->result->tuples_removed); if (!tmpitems) { /* diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c index aac4afab8f..8a0f23388b 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,7 @@ restart: END_CRIT_SECTION(); vstate->stats->tuples_removed += ntodelete; + pgstat_progress_update_param(PROGRESS_VACUUM_TUPLES_REMOVED, 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 a259a301fa..23dacee52e 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -632,6 +632,7 @@ loop_top: stats->estimated_count = false; stats->num_index_tuples = num_index_tuples; stats->tuples_removed += tuples_removed; + pgstat_progress_update_param(PROGRESS_VACUUM_TUPLES_REMOVED, 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 047a5db494..1cc3fae20c 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -348,6 +348,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, MyProcPid); /* * Get OldestXmin cutoff, which is used to determine which deleted tuples @@ -2326,12 +2327,19 @@ lazy_vacuum_all_indexes(LVRelState *vacrel) Relation indrel = vacrel->indrels[idx]; IndexBulkDeleteResult *istat = vacrel->indstats[idx]; + /* Advertise the index being vacuumed in non-parallel vacuum */ + pgstat_progress_update_param(PROGRESS_VACUUM_INDEXRELID, RelationGetRelid(indrel)); + vacrel->indstats[idx] = lazy_vacuum_one_index(indrel, istat, vacrel->old_live_tuples, vacrel); pgstat_progress_update_param(PROGRESS_VACUUM_INDEXES_PROCESSED, indexes_processed++); + /* Advertise we are done vacuuming indexes in non-parallel vacuum */ + pgstat_progress_update_param(PROGRESS_VACUUM_INDEXRELID, 0); + pgstat_progress_update_param(PROGRESS_VACUUM_TUPLES_REMOVED, 0); + if (lazy_check_wraparound_failsafe(vacrel)) { /* Wraparound emergency -- end current index scan */ @@ -2701,11 +2709,17 @@ lazy_cleanup_all_indexes(LVRelState *vacrel) Relation indrel = vacrel->indrels[idx]; IndexBulkDeleteResult *istat = vacrel->indstats[idx]; + /* Advertise the index being cleaned in non-parallel vacuum */ + pgstat_progress_update_param(PROGRESS_VACUUM_INDEXRELID, RelationGetRelid(indrel)); + vacrel->indstats[idx] = lazy_cleanup_one_index(indrel, istat, reltuples, estimated_count, vacrel); pgstat_progress_update_param(PROGRESS_VACUUM_INDEXES_PROCESSED, indexes_processed++); + + /* Advertise we are done cleaning indexes in non-parallel vacuum */ + pgstat_progress_update_param(PROGRESS_VACUUM_INDEXRELID, 0); } } else diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index c9b4964c1e..09edf49082 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -1273,6 +1273,7 @@ backtrack: nupdatable); stats->tuples_removed += nhtidsdead; + pgstat_progress_update_param(PROGRESS_VACUUM_TUPLES_REMOVED, 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..db73f8ef59 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_TUPLES_REMOVED, 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_TUPLES_REMOVED, bds->stats->tuples_removed); } else { diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 35ea25026f..88375aad0a 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -1129,7 +1129,23 @@ CREATE VIEW pg_stat_progress_vacuum AS S.param6 AS max_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') 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.param12; + +CREATE VIEW pg_stat_progress_vacuum_index AS + SELECT + S.pid AS pid, + S.datid AS datid, + D.datname AS datname, + S.param10 AS indexrelid, + S.param12 AS leader_pid, + CASE S.param1 WHEN 2 THEN 'vacuuming indexes' + WHEN 4 THEN 'cleaning up indexes' + END AS phase, + S.param11 AS tuples_removed + FROM pg_stat_get_progress_info('VACUUM') AS S + LEFT JOIN pg_database D ON S.datid = D.oid + WHERE S.param1 IN (2, 4) AND S.param10 > 0; CREATE VIEW pg_stat_progress_cluster AS SELECT diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c index f08eb837e7..7d47565e05 100644 --- a/src/backend/commands/vacuumparallel.c +++ b/src/backend/commands/vacuumparallel.c @@ -845,13 +845,18 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel, pvs->indname = pstrdup(RelationGetRelationName(indrel)); pvs->status = indstats->status; + /* Advertise the index we are cleaning or vacuuming */ + pgstat_progress_update_param(PROGRESS_VACUUM_INDEXRELID, RelationGetRelid(indrel)); + switch (indstats->status) { case PARALLEL_INDVAC_STATUS_NEED_BULKDELETE: + pgstat_progress_update_param(PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_PHASE_VACUUM_INDEX); istat_res = vac_bulkdel_one_index(&ivinfo, istat, pvs->dead_items); pgstat_progress_update_param_parallel(pvs->shared->leader_pid, PROGRESS_VACUUM_INDEXES_PROCESSED, 1); break; case PARALLEL_INDVAC_STATUS_NEED_CLEANUP: + pgstat_progress_update_param(PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_PHASE_INDEX_CLEANUP); istat_res = vac_cleanup_one_index(&ivinfo, istat); pgstat_progress_update_param_parallel(pvs->shared->leader_pid, PROGRESS_VACUUM_INDEXES_PROCESSED, 1); break; @@ -888,6 +893,10 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel, */ indstats->status = PARALLEL_INDVAC_STATUS_COMPLETED; + /* Advertise we are no longer vacuuming/cleaning an index */ + pgstat_progress_update_param(PROGRESS_VACUUM_INDEXRELID, 0); + pgstat_progress_update_param(PROGRESS_VACUUM_TUPLES_REMOVED, 0); + /* Reset error traceback information */ pvs->status = PARALLEL_INDVAC_STATUS_COMPLETED; pfree(pvs->indname); @@ -972,6 +981,8 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) * workers. */ rel = table_open(shared->relid, ShareUpdateExclusiveLock); + pgstat_progress_start_command(PROGRESS_COMMAND_VACUUM, RelationGetRelid(rel)); + pgstat_progress_update_param(PROGRESS_VACUUM_LEADER_PID, shared->leader_pid); /* * Open all indexes. indrels are sorted in order by OID, which should be @@ -1042,6 +1053,7 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) vac_close_indexes(nindexes, indrels, RowExclusiveLock); table_close(rel, ShareUpdateExclusiveLock); + pgstat_progress_end_command(); FreeAccessStrategy(pvs.bstrategy); } diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h index 54ee60caad..7e632feb7d 100644 --- a/src/include/commands/progress.h +++ b/src/include/commands/progress.h @@ -27,6 +27,9 @@ #define PROGRESS_VACUUM_NUM_DEAD_TUPLES 6 #define PROGRESS_VACUUM_TOTAL_INDEXES 7 #define PROGRESS_VACUUM_INDEXES_PROCESSED 8 +#define PROGRESS_VACUUM_INDEXRELID 9 +#define PROGRESS_VACUUM_TUPLES_REMOVED 10 +#define PROGRESS_VACUUM_LEADER_PID 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 d70a176514..d2c66bf034 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -2006,7 +2006,22 @@ pg_stat_progress_vacuum| SELECT s.pid, 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))); + LEFT JOIN pg_database d ON ((s.datid = d.oid))) + WHERE (s.pid = s.param12); +pg_stat_progress_vacuum_index| SELECT s.pid, + s.datid, + d.datname, + s.param10 AS indexrelid, + s.param12 AS leader_pid, + CASE s.param1 + WHEN 2 THEN 'vacuuming indexes'::text + WHEN 4 THEN 'cleaning up indexes'::text + ELSE NULL::text + END AS phase, + s.param11 AS 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.param1 = ANY (ARRAY[(2)::bigint, (4)::bigint])) AND (s.param10 > 0)); pg_stat_replication| SELECT s.pid, s.usesysid, u.rolname AS usename, -- 2.32.0
v8-0004-Rename-index_vacuum_count-in-pg_stat_pogress_vacu.patch (application/octet-stream, 2.8K) download From 5303ab5d4d1f11a1a0fe62f28f74b13e2df9e3a2 Mon Sep 17 00:00:00 2001 From: "Sami Imseih (AWS)" <simseih@amazon.com> Date: Mon, 14 Mar 2022 22:08:04 +0000 Subject: [PATCH v8 4/4] Rename "index_vacuum_count" in pg_stat_pogress_vacuum. Commit 76d8a1bfd5207d28a4e9fe98a0e1ea7c096d70aa introduces 2 new columns to track index vacuum/cleanup progress. The columns have "index" in the name. To make it clear what the existing "index_vacuum_count" column refers to, which is the cycle count of the index vacuum, this change renames the column to "index_vacuum_count" 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/flat/5478DFCD-2333-401A-B2F0-0D186AB09228@amazon.com --- doc/src/sgml/monitoring.sgml | 2 +- src/backend/catalog/system_views.sql | 2 +- src/test/regress/expected/rules.out | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 240d2438d5..1e5af0b400 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -6210,7 +6210,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, <row> <entry role="catalog_table_entry"><para role="column_definition"> - <structfield>index_vacuum_count</structfield> <type>bigint</type> + <structfield>index_vacuum_cycle_count</structfield> <type>bigint</type> </para> <para> Number of completed index vacuum cycles. diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 88375aad0a..639ad00a71 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -1125,7 +1125,7 @@ CREATE VIEW pg_stat_progress_vacuum AS WHEN 6 THEN 'performing final cleanup' 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.param4 AS heap_blks_vacuumed, S.param5 AS index_vacuum_cycle_count, S.param6 AS max_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') AS S diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index d2c66bf034..7a6bf3af27 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -2000,7 +2000,7 @@ pg_stat_progress_vacuum| SELECT s.pid, 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.param5 AS index_vacuum_cycle_count, s.param6 AS max_dead_tuples, s.param7 AS num_dead_tuples, s.param8 AS indexes_total, -- 2.32.0

view thread (139+ messages)  latest in thread

Message-ID: <4F14170D-AF67-4FDF-9EB0-2A1F8EA14899@amazon.com>
Permalink:  ../4F14170D-AF67-4FDF-9EB0-2A1F8EA14899@amazon.com/
Also on:    postgresql.org/message-id/4F14170D-AF67-4FDF-9EB0-2A1F8EA14899@amazon.com

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: simseih@amazon.com, sawada.mshk@gmail.com, nathandbossart@gmail.com, pg@bowt.ie, bossartn@amazon.com, pryzby@telsasoft.com
  Subject: Re: Add index scan progress to pg_stat_progress_vacuum
  In-Reply-To: <4F14170D-AF67-4FDF-9EB0-2A1F8EA14899@amazon.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox