From f44ee1b30249fc62418725279356a0959d27e864 Mon Sep 17 00:00:00 2001 From: Ilya Gladyshev Date: Tue, 31 Jan 2023 19:13:07 +0400 Subject: [PATCH v3] create index progress increment --- doc/src/sgml/monitoring.sgml | 4 +- src/backend/commands/indexcmds.c | 64 +++++++++++++++++-- src/backend/utils/activity/backend_progress.c | 25 ++++++++ src/include/utils/backend_progress.h | 1 + 4 files changed, 87 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..936b4e3c1d 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -130,6 +130,30 @@ 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 +1243,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); @@ -1250,6 +1280,7 @@ DefineIndex(Oid relationId, { Oid childRelid = part_oids[i]; Relation childrel; + char child_relkind; Oid child_save_userid; int child_save_sec_context; int child_save_nestlevel; @@ -1259,6 +1290,7 @@ DefineIndex(Oid relationId, bool found = false; childrel = table_open(childRelid, lockmode); + child_relkind = RelationGetForm(childrel)->relkind; GetUserIdAndSecContext(&child_save_userid, &child_save_sec_context); @@ -1431,9 +1463,25 @@ DefineIndex(Oid relationId, SetUserIdAndSecContext(child_save_userid, child_save_sec_context); } + else + { + int attached_parts = 1; + + if (RELKIND_HAS_PARTITIONS(child_relkind)) + attached_parts = count_leaf_partitions(childRelid); + + /* + * If the index was attached, we need to update progress + * here, in its parent. For a partitioned index, we need + * to mark all of its children that were included in + * PROGRESS_CREATEIDX_PARTITIONS_TOTAL as done. 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, attached_parts); + } - pgstat_progress_update_param(PROGRESS_CREATEIDX_PARTITIONS_DONE, - i + 1); free_attrmap(attmap); } @@ -1484,9 +1532,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)