From 03f716bb9b1a79884655d87a6b3986a622aa4285 Mon Sep 17 00:00:00 2001 From: "Imseih (AWS)" Date: Wed, 2 Nov 2022 10:36:10 -0500 Subject: [PATCH 1/1] Function to return currently vacuumed ( or cleaned ) index pg_stat_get_vacuum_index takes a PID as an argument and returns the index relid of the currently vacuumed index. NULL is returned if the backend is not involved in an index vacuum. --- doc/src/sgml/func.sgml | 13 +++++++ doc/src/sgml/monitoring.sgml | 8 +++-- src/backend/access/heap/vacuumlazy.c | 9 +++++ src/backend/commands/vacuumparallel.c | 23 ++++++++++++ src/backend/utils/adt/pgstatfuncs.c | 52 +++++++++++++++++++++++++++ src/include/catalog/pg_proc.dat | 4 +++ src/include/commands/progress.h | 1 + src/include/utils/backend_progress.h | 7 +++- 8 files changed, 114 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 6e0425cb3d..39841354de 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -22670,6 +22670,19 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); parsing the text version. + + + + + pg_stat_get_vacuum_index + + pg_stat_get_vacuum_index ( integer ) + oid + + + Returns the relid of an index current being vacuumed or cleaned by the backend. + + diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index c61443f3d5..8d947d8c3a 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -6517,7 +6517,9 @@ FROM pg_stat_get_backend_idset() AS backendid; has been completely scanned. It may happen multiple times per vacuum if (or, in the case of autovacuum, if set) is insufficient to store - the number of dead tuples found. + the number of dead tuples found. While in this phase, the function + pg_stat_get_vacuum_index() will return the relid + of the index being vacuumed. @@ -6536,7 +6538,9 @@ FROM pg_stat_get_backend_idset() AS backendid; VACUUM is currently cleaning up indexes. This occurs after the heap has been completely scanned and all vacuuming of the indexes - and the heap has been completed. + and the heap has been completed. While in this phase, the function + pg_stat_get_vacuum_index() will return the relid + of the index being cleaned. diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 120a2b18d7..8cd8e34f88 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -350,6 +350,7 @@ heap_vacuum_rel(Relation rel, VacuumParams *params, } } + /* start the vacuum progress command and report to progress.h */ pgstat_progress_start_command(PROGRESS_COMMAND_VACUUM, RelationGetRelid(rel)); @@ -2341,6 +2342,9 @@ lazy_vacuum_all_indexes(LVRelState *vacrel) Relation indrel = vacrel->indrels[idx]; IndexBulkDeleteResult *istat = vacrel->indstats[idx]; + /* report the index relid being vacuumed */ + pgstat_progress_update_param(PROGRESS_VACUUM_INDRELID, RelationGetRelid(indrel)); + vacrel->indstats[idx] = lazy_vacuum_one_index(indrel, istat, vacrel->old_live_tuples, vacrel); @@ -2350,6 +2354,7 @@ lazy_vacuum_all_indexes(LVRelState *vacrel) */ pgstat_progress_update_param(PROGRESS_VACUUM_INDEX_COMPLETED, idx + 1); + pgstat_progress_update_param(PROGRESS_VACUUM_INDRELID, 0); if (lazy_check_wraparound_failsafe(vacrel)) { @@ -2705,6 +2710,9 @@ lazy_cleanup_all_indexes(LVRelState *vacrel) Relation indrel = vacrel->indrels[idx]; IndexBulkDeleteResult *istat = vacrel->indstats[idx]; + /* report the index relid being cleaned */ + pgstat_progress_update_param(PROGRESS_VACUUM_INDRELID, RelationGetRelid(indrel)); + vacrel->indstats[idx] = lazy_cleanup_one_index(indrel, istat, reltuples, estimated_count, vacrel); @@ -2714,6 +2722,7 @@ lazy_cleanup_all_indexes(LVRelState *vacrel) */ pgstat_progress_update_param(PROGRESS_VACUUM_INDEX_COMPLETED, idx + 1); + pgstat_progress_update_param(PROGRESS_VACUUM_INDRELID, 0); } } else diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c index 85e2de5d54..f2f51e86eb 100644 --- a/src/backend/commands/vacuumparallel.c +++ b/src/backend/commands/vacuumparallel.c @@ -840,6 +840,20 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel, IndexBulkDeleteResult *istat = NULL; IndexBulkDeleteResult *istat_res; IndexVacuumInfo ivinfo; + Oid indrelid = RelationGetRelid(indrel); + + /* + * If we are a parallel worker, start a PROGRESS_COMMAND_VACUUM_PARALLEL + * command for progress reporting and report the index being vacuumed. + */ + if (IsParallelWorker()) + { + pgstat_progress_start_command(PROGRESS_COMMAND_VACUUM_PARALLEL, + pvs->shared->relid); + } + + /* report the index being vacuumed or cleaned up */ + pgstat_progress_update_param(PROGRESS_VACUUM_INDRELID, indrelid); /* * Update the pointer to the corresponding bulk-deletion result if someone @@ -911,10 +925,19 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel, pfree(pvs->indname); pvs->indname = NULL; + /* + * Reset the index relid begin vacuumed/cleaned + */ + pgstat_progress_update_param(PROGRESS_VACUUM_INDRELID, 0); + /* * Update the number of indexes completed. */ pg_atomic_add_fetch_u32(&(pvs->shared->idx_completed_progress), 1); + + /* if we are a parallel worker, end the command */ + if (IsParallelWorker()) + pgstat_progress_end_command(); } /* diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 96bffc0f2a..b08c15e7aa 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -19,6 +19,7 @@ #include "access/xlogprefetcher.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" @@ -2383,3 +2384,54 @@ pg_stat_have_stats(PG_FUNCTION_ARGS) PG_RETURN_BOOL(pgstat_have_entry(kind, dboid, objoid)); } + +/* + * For a given PID, return the relid of the index + * currently being vacuumed. + */ +Datum +pg_stat_get_vacuum_index(PG_FUNCTION_ARGS) +{ + int pid = PG_GETARG_INT32(0); + int num_backends = pgstat_fetch_stat_numbackends(); + int curr_backend; + Oid indrelid = 0; + ProgressCommandType cmdtype_vacuum = PROGRESS_COMMAND_VACUUM; + ProgressCommandType cmdtype_vacuum_parallel = PROGRESS_COMMAND_VACUUM_PARALLEL; + + /* 1-based index */ + for (curr_backend = 1; curr_backend <= num_backends; curr_backend++) + { + LocalPgBackendStatus *local_beentry; + PgBackendStatus *beentry; + + local_beentry = pgstat_fetch_stat_local_beentry(curr_backend); + beentry = &local_beentry->backendStatus; + + /* + * If a backend has a VACUUM or VACUUM_PARALLEL progress command type + * and the procpid matches the given PID, return the index relid id + * that is current being vacuumed. In some cases, the index relid could + * be a '0' if we got here at thhe end of a vacuum or when no indexes + * are being vacuumed. In this case return NULL. + */ + if ( + (beentry->st_progress_command == cmdtype_vacuum + || beentry->st_progress_command == cmdtype_vacuum_parallel) && + beentry->st_procpid == pid + ) + { + indrelid = Int64GetDatum(beentry->st_progress_param[PROGRESS_VACUUM_INDRELID]); + + if (indrelid > 0) + PG_RETURN_OID(indrelid); + else + PG_RETURN_NULL(); + } + } + + /* + * No matching PID performing a VACUUM operation, return NULL. + */ + PG_RETURN_NULL(); +} \ No newline at end of file diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 20f5aa56ea..dd5a32172a 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -11827,5 +11827,9 @@ proname => 'brin_minmax_multi_summary_send', provolatile => 's', prorettype => 'bytea', proargtypes => 'pg_brin_minmax_multi_summary', prosrc => 'brin_minmax_multi_summary_send' }, +{ oid => '4642', + descr => 'get the relid of the index being vacuumed by a backend', + proname => 'pg_stat_get_vacuum_index', provolatile => 'v', prorettype => 'int8', + proargtypes => 'int4', prosrc => 'pg_stat_get_vacuum_index' }, ] diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h index 0e97c6d4ef..bc2b7d1e95 100644 --- a/src/include/commands/progress.h +++ b/src/include/commands/progress.h @@ -27,6 +27,7 @@ #define PROGRESS_VACUUM_NUM_DEAD_TUPLES 6 #define PROGRESS_VACUUM_INDEX_TOTAL 7 #define PROGRESS_VACUUM_INDEX_COMPLETED 8 +#define PROGRESS_VACUUM_INDRELID 9 /* Phases of vacuum (as advertised via PROGRESS_VACUUM_PHASE) */ #define PROGRESS_VACUUM_PHASE_SCAN_HEAP 1 diff --git a/src/include/utils/backend_progress.h b/src/include/utils/backend_progress.h index 47bf8029b0..74d9dfb4c7 100644 --- a/src/include/utils/backend_progress.h +++ b/src/include/utils/backend_progress.h @@ -17,6 +17,10 @@ /* ---------- * Command type for progress reporting purposes + * + * Note: PROGRESS_COMMAND_VACUUM_PARALLEL is not + * a command per se, but this type is used to track + * parallel vacuum workers progress. * ---------- */ typedef enum ProgressCommandType @@ -27,7 +31,8 @@ typedef enum ProgressCommandType PROGRESS_COMMAND_CLUSTER, PROGRESS_COMMAND_CREATE_INDEX, PROGRESS_COMMAND_BASEBACKUP, - PROGRESS_COMMAND_COPY + PROGRESS_COMMAND_COPY, + PROGRESS_COMMAND_VACUUM_PARALLEL } ProgressCommandType; #define PGSTAT_NUM_PROGRESS_PARAM 20 -- 2.32.1 (Apple Git-133)