From 5f377fc90f86ee08a2c9487c4bbb2d48f0a25777 Mon Sep 17 00:00:00 2001 From: Ilya Gladyshev Date: Tue, 31 Jan 2023 19:13:07 +0400 Subject: [PATCH] create index progress increment --- doc/src/sgml/monitoring.sgml | 4 +- src/backend/commands/indexcmds.c | 51 +++++++++++++++++-- src/backend/utils/activity/backend_progress.c | 27 ++++++++++ src/include/utils/backend_progress.h | 1 + 4 files changed, 76 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..a6c1889ed1 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,16 @@ DefineIndex(Oid relationId, SetUserIdAndSecContext(child_save_userid, child_save_sec_context); } + else + { + /* + * If the index has been attached, count all of its leaf indexes as attached, + * because PROGRESS_CREATEIDX_PARTITIONS_TOTAL includes them all initially. + */ + 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 +1520,14 @@ 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, otherwise, increment + * done partition counter, if the counter is initialized. + */ 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..64a4406e0b 100644 --- a/src/backend/utils/activity/backend_progress.c +++ b/src/backend/utils/activity/backend_progress.c @@ -58,6 +58,33 @@ 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; + int before_changecount PG_USED_FOR_ASSERTS_ONLY; + int after_changecount PG_USED_FOR_ASSERTS_ONLY; + + Assert(index >= 0 && index < PGSTAT_NUM_PROGRESS_PARAM); + + if (!beentry || !pgstat_track_activities) + return; + + /* Because 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_BEGIN_WRITE_ACTIVITY(beentry); + beentry->st_progress_param[index] = val; + PGSTAT_END_WRITE_ACTIVITY(beentry); +} + /*----------- * pgstat_progress_update_multi_param() - * diff --git a/src/include/utils/backend_progress.h b/src/include/utils/backend_progress.h index 005e5d75ab..afedd22d11 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 val); 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)