From 94ec0a5762b78c571127999be9e051ba74d88424 Mon Sep 17 00:00:00 2001 From: Ilya Gladyshev Date: Tue, 31 Jan 2023 19:13:07 +0400 Subject: [PATCH v2] create index progress increment --- doc/src/sgml/monitoring.sgml | 4 +- src/backend/commands/indexcmds.c | 54 +++++++++++++++++-- src/backend/utils/activity/backend_progress.c | 25 +++++++++ src/include/utils/backend_progress.h | 1 + 4 files changed, 77 insertions(+), 7 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 1756f1a4b6..a911900271 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -6601,7 +6601,7 @@ FROM pg_stat_get_backend_idset() AS backendid; When creating an index on a partitioned table, this column is set to - the total number of partitions on which the index is to be created. + the total number of leaf partitions on which the index is to be created or attached. This field is 0 during a REINDEX. @@ -6612,7 +6612,7 @@ FROM pg_stat_get_backend_idset() AS backendid; When creating an index on a partitioned table, this column is set to - the number of partitions on which the index has been created. + the number of leaf partitions on which the index has been created or attached. This field is 0 during a REINDEX. diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 16ec0b114e..0f925c3a69 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -130,6 +130,29 @@ typedef struct ReindexErrorInfo char relkind; } ReindexErrorInfo; + +/* + * Count the number of direct and indirect leaf partitions, excluding foreign + * tables. + */ +static int +count_leaf_partitions(Oid relid) +{ + int nleaves = 0; + List *childs = find_all_inheritors(relid, NoLock, NULL); + ListCell *lc; + + foreach(lc, childs) + { + Oid partrelid = lfirst_oid(lc); + if (RELKIND_HAS_STORAGE(get_rel_relkind(partrelid))) + nleaves++; + } + + list_free(childs); + return nleaves; +} + /* * CheckIndexCompatible * Determine whether an existing index definition is compatible with a @@ -1219,8 +1242,14 @@ DefineIndex(Oid relationId, Relation parentIndex; TupleDesc parentDesc; - pgstat_progress_update_param(PROGRESS_CREATEIDX_PARTITIONS_TOTAL, - nparts); + if (!OidIsValid(parentIndexId)) + { + int total_parts; + + total_parts = count_leaf_partitions(relationId); + pgstat_progress_update_param(PROGRESS_CREATEIDX_PARTITIONS_TOTAL, + total_parts); + } /* Make a local copy of partdesc->oids[], just for safety */ memcpy(part_oids, partdesc->oids, sizeof(Oid) * nparts); @@ -1431,9 +1460,18 @@ DefineIndex(Oid relationId, SetUserIdAndSecContext(child_save_userid, child_save_sec_context); } + else + { + /* + * If the index was attached, update progress for all its direct and + * indirect leaf indexes all at once. If the index was built by calling + * DefineIndex() recursively, the called function is responsible for + * updating the progress report for built indexes. + */ + pgstat_progress_incr_param(PROGRESS_CREATEIDX_PARTITIONS_DONE, + count_leaf_partitions(childRelid)); + } - pgstat_progress_update_param(PROGRESS_CREATEIDX_PARTITIONS_DONE, - i + 1); free_attrmap(attmap); } @@ -1484,9 +1522,15 @@ DefineIndex(Oid relationId, /* Close the heap and we're done, in the non-concurrent case */ table_close(rel, NoLock); - /* If this is the top-level index, we're done. */ + /* + * If this is the top-level index, we're done. When called recursively + * for child tables, the done partition counter is incremented now, + * rather than in the caller. + */ if (!OidIsValid(parentIndexId)) pgstat_progress_end_command(); + else + pgstat_progress_incr_param(PROGRESS_CREATEIDX_PARTITIONS_DONE, 1); return address; } diff --git a/src/backend/utils/activity/backend_progress.c b/src/backend/utils/activity/backend_progress.c index d96af812b1..45f7e7144b 100644 --- a/src/backend/utils/activity/backend_progress.c +++ b/src/backend/utils/activity/backend_progress.c @@ -58,6 +58,31 @@ pgstat_progress_update_param(int index, int64 val) PGSTAT_END_WRITE_ACTIVITY(beentry); } +/*----------- + * pgstat_progress_incr_param() - + * + * Increment index'th member in st_progress_param[] of own backend entry. + *----------- + */ +void pgstat_progress_incr_param(int index, int64 incr) { + volatile PgBackendStatus *beentry = MyBEEntry; + int64 val; + + Assert(index >= 0 && index < PGSTAT_NUM_PROGRESS_PARAM); + + if (!beentry || !pgstat_track_activities) + return; + + /* + * Because current backend is the only process that writes to its own status, + * we don't need to do the looping to read the value. + */ + val = beentry->st_progress_param[index]; + val += incr; + + pgstat_progress_update_param(index, val); +} + /*----------- * pgstat_progress_update_multi_param() - * diff --git a/src/include/utils/backend_progress.h b/src/include/utils/backend_progress.h index 005e5d75ab..a84752ade9 100644 --- a/src/include/utils/backend_progress.h +++ b/src/include/utils/backend_progress.h @@ -36,6 +36,7 @@ typedef enum ProgressCommandType extern void pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid); extern void pgstat_progress_update_param(int index, int64 val); +extern void pgstat_progress_incr_param(int index, int64 incr); extern void pgstat_progress_update_multi_param(int nparam, const int *index, const int64 *val); extern void pgstat_progress_end_command(void); -- 2.37.1 (Apple Git-137.1)