On Thu, Nov 07, 2024 at 02:36:58PM +0900, Michael Paquier wrote: > Incorrect comment format, about which pgindent does not complain.. > > .. But pgindent complains in execMain.c and pgstat_database.c. These > are only nits, the patch is fine. If anybody has objections or > comments, feel free.
Found a few more things, but overall it was fine. Here is what I have staged on my local branch. -- Michael
From 960fbe663d4a6a4594b8121bbf299c72ef2a6ab8 Mon Sep 17 00:00:00 2001 From: Michael Paquier <mich...@paquier.xyz> Date: Fri, 8 Nov 2024 13:00:26 +0900 Subject: [PATCH v7] Add two attributes to pg_stat_database for parallel workers activity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two attributes are added to pg_stat_database: * parallel_workers_to_launch, counting the total number of parallel workers that were planned to be launched. * parallel_workers_launched, counting the total number of parallel workers actually launched. The ratio of both fields can provide hints that there are not enough slots available when launching parallel workers. This commit relies on de3a2ea3b264, that has added two fields to EState, that get incremented when executing Gather or GatherMerge nodes. The data now gets pushed to pg_stat_database, which is useful how much a database faces contention when spawning parallel workers if pg_stat_statements is not enabled on an instance. Bump catalog version. Author: Benoit Lobréau Discussion: https://postgr.es/m/783bc7f7-659a-42fa-99dd-ee0565644...@dalibo.com --- src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_proc.dat | 10 +++++++ src/include/pgstat.h | 4 +++ src/backend/catalog/system_views.sql | 2 ++ src/backend/executor/execMain.c | 5 ++++ src/backend/utils/activity/pgstat_database.c | 19 +++++++++++++ src/backend/utils/adt/pgstatfuncs.c | 6 +++++ src/test/regress/expected/rules.out | 2 ++ src/test/regress/expected/select_parallel.out | 27 +++++++++++++++++++ src/test/regress/sql/select_parallel.sql | 14 ++++++++++ doc/src/sgml/monitoring.sgml | 18 +++++++++++++ 11 files changed, 108 insertions(+), 1 deletion(-) diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 2abc523f5c..86436e0356 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202411071 +#define CATALOG_VERSION_NO 202411081 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f23321a41f..cbbe8acd38 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -5813,6 +5813,16 @@ proname => 'pg_stat_get_db_sessions_killed', provolatile => 's', proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', prosrc => 'pg_stat_get_db_sessions_killed' }, +{ oid => '8403', + descr => 'statistics: number of parallel workers planned to be launched by queries', + proname => 'pg_stat_get_db_parallel_workers_to_launch', provolatile => 's', + proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_db_parallel_workers_to_launch' }, +{ oid => '8404', + descr => 'statistics: number of parallel workers effectively launched by queries', + proname => 'pg_stat_get_db_parallel_workers_launched', provolatile => 's', + proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_db_parallel_workers_launched' }, { oid => '3195', descr => 'statistics: information about WAL archiver', proname => 'pg_stat_get_archiver', proisstrict => 'f', provolatile => 's', proparallel => 'r', prorettype => 'record', proargtypes => '', diff --git a/src/include/pgstat.h b/src/include/pgstat.h index df53fa2d4f..59c28b4aca 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -386,6 +386,8 @@ typedef struct PgStat_StatDBEntry PgStat_Counter sessions_abandoned; PgStat_Counter sessions_fatal; PgStat_Counter sessions_killed; + PgStat_Counter parallel_workers_to_launch; + PgStat_Counter parallel_workers_launched; TimestampTz stat_reset_timestamp; } PgStat_StatDBEntry; @@ -583,6 +585,8 @@ extern void pgstat_report_deadlock(void); extern void pgstat_report_checksum_failures_in_db(Oid dboid, int failurecount); extern void pgstat_report_checksum_failure(void); extern void pgstat_report_connect(Oid dboid); +extern void pgstat_update_parallel_workers_stats(PgStat_Counter workers_to_launch, + PgStat_Counter workers_launched); #define pgstat_count_buffer_read_time(n) \ (pgStatBlockReadTime += (n)) diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 3456b821bc..da9a8fe99f 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -1073,6 +1073,8 @@ CREATE VIEW pg_stat_database AS pg_stat_get_db_sessions_abandoned(D.oid) AS sessions_abandoned, pg_stat_get_db_sessions_fatal(D.oid) AS sessions_fatal, pg_stat_get_db_sessions_killed(D.oid) AS sessions_killed, + pg_stat_get_db_parallel_workers_to_launch(D.oid) as parallel_workers_to_launch, + pg_stat_get_db_parallel_workers_launched(D.oid) as parallel_workers_launched, pg_stat_get_db_stat_reset_time(D.oid) AS stats_reset FROM ( SELECT 0 AS oid, NULL::name AS datname diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index cc9a594cba..5ca856fd27 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -52,6 +52,7 @@ #include "miscadmin.h" #include "nodes/queryjumble.h" #include "parser/parse_relation.h" +#include "pgstat.h" #include "rewrite/rewriteHandler.h" #include "tcop/utility.h" #include "utils/acl.h" @@ -483,6 +484,10 @@ standard_ExecutorEnd(QueryDesc *queryDesc) Assert(estate != NULL); + if (estate->es_parallel_workers_to_launch > 0) + pgstat_update_parallel_workers_stats((PgStat_Counter) estate->es_parallel_workers_to_launch, + (PgStat_Counter) estate->es_parallel_workers_launched); + /* * Check that ExecutorFinish was called, unless in EXPLAIN-only mode. This * Assert is needed because ExecutorFinish is new as of 9.1, and callers diff --git a/src/backend/utils/activity/pgstat_database.c b/src/backend/utils/activity/pgstat_database.c index 29bc090974..7757d2ace7 100644 --- a/src/backend/utils/activity/pgstat_database.c +++ b/src/backend/utils/activity/pgstat_database.c @@ -262,6 +262,23 @@ AtEOXact_PgStat_Database(bool isCommit, bool parallel) } } +/* + * Notify the stats system about parallel worker information. + */ +void +pgstat_update_parallel_workers_stats(PgStat_Counter workers_to_launch, + PgStat_Counter workers_launched) +{ + PgStat_StatDBEntry *dbentry; + + if (!OidIsValid(MyDatabaseId)) + return; + + dbentry = pgstat_prep_database_pending(MyDatabaseId); + dbentry->parallel_workers_to_launch += workers_to_launch; + dbentry->parallel_workers_launched += workers_launched; +} + /* * Subroutine for pgstat_report_stat(): Handle xact commit/rollback and I/O * timings. @@ -425,6 +442,8 @@ pgstat_database_flush_cb(PgStat_EntryRef *entry_ref, bool nowait) PGSTAT_ACCUM_DBCOUNT(sessions_abandoned); PGSTAT_ACCUM_DBCOUNT(sessions_fatal); PGSTAT_ACCUM_DBCOUNT(sessions_killed); + PGSTAT_ACCUM_DBCOUNT(parallel_workers_to_launch); + PGSTAT_ACCUM_DBCOUNT(parallel_workers_launched); #undef PGSTAT_ACCUM_DBCOUNT pgstat_unlock_entry(entry_ref); diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index f7b50e0b5a..60a397dc56 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -1039,6 +1039,12 @@ PG_STAT_GET_DBENTRY_INT64(sessions_fatal) /* pg_stat_get_db_sessions_killed */ PG_STAT_GET_DBENTRY_INT64(sessions_killed) +/* pg_stat_get_db_parallel_workers_to_launch */ +PG_STAT_GET_DBENTRY_INT64(parallel_workers_to_launch) + +/* pg_stat_get_db_parallel_workers_launched */ +PG_STAT_GET_DBENTRY_INT64(parallel_workers_launched) + /* pg_stat_get_db_temp_bytes */ PG_STAT_GET_DBENTRY_INT64(temp_bytes) diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 2b47013f11..3014d047fe 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1863,6 +1863,8 @@ pg_stat_database| SELECT oid AS datid, pg_stat_get_db_sessions_abandoned(oid) AS sessions_abandoned, pg_stat_get_db_sessions_fatal(oid) AS sessions_fatal, pg_stat_get_db_sessions_killed(oid) AS sessions_killed, + pg_stat_get_db_parallel_workers_to_launch(oid) AS parallel_workers_to_launch, + pg_stat_get_db_parallel_workers_launched(oid) AS parallel_workers_launched, pg_stat_get_db_stat_reset_time(oid) AS stats_reset FROM ( SELECT 0 AS oid, NULL::name AS datname diff --git a/src/test/regress/expected/select_parallel.out b/src/test/regress/expected/select_parallel.out index d17ade278b..8c31f6460d 100644 --- a/src/test/regress/expected/select_parallel.out +++ b/src/test/regress/expected/select_parallel.out @@ -1,6 +1,17 @@ -- -- PARALLEL -- +-- Save parallel worker stats, used for comparison at the end +select pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +select parallel_workers_to_launch as parallel_workers_to_launch_before, + parallel_workers_launched as parallel_workers_launched_before + from pg_stat_database + where datname = current_database() \gset create function sp_parallel_restricted(int) returns int as $$begin return $1; end$$ language plpgsql parallel restricted; begin; @@ -1407,3 +1418,19 @@ CREATE UNIQUE INDEX parallel_hang_idx SET debug_parallel_query = on; DELETE FROM parallel_hang WHERE 380 <= i AND i <= 420; ROLLBACK; +-- Check parallel worker stats +select pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +select parallel_workers_to_launch > :'parallel_workers_to_launch_before' AS wrk_to_launch, + parallel_workers_launched > :'parallel_workers_launched_before' AS wrk_launched + from pg_stat_database + where datname = current_database(); + wrk_to_launch | wrk_launched +---------------+-------------- + t | t +(1 row) + diff --git a/src/test/regress/sql/select_parallel.sql b/src/test/regress/sql/select_parallel.sql index 9ba1328fd2..5b4a6e1088 100644 --- a/src/test/regress/sql/select_parallel.sql +++ b/src/test/regress/sql/select_parallel.sql @@ -2,6 +2,13 @@ -- PARALLEL -- +-- Save parallel worker stats, used for comparison at the end +select pg_stat_force_next_flush(); +select parallel_workers_to_launch as parallel_workers_to_launch_before, + parallel_workers_launched as parallel_workers_launched_before + from pg_stat_database + where datname = current_database() \gset + create function sp_parallel_restricted(int) returns int as $$begin return $1; end$$ language plpgsql parallel restricted; @@ -574,3 +581,10 @@ SET debug_parallel_query = on; DELETE FROM parallel_hang WHERE 380 <= i AND i <= 420; ROLLBACK; + +-- Check parallel worker stats +select pg_stat_force_next_flush(); +select parallel_workers_to_launch > :'parallel_workers_to_launch_before' AS wrk_to_launch, + parallel_workers_launched > :'parallel_workers_launched_before' AS wrk_launched + from pg_stat_database + where datname = current_database(); diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 331315f8d3..840d7f8161 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -3611,6 +3611,24 @@ description | Waiting for a newly initialized WAL file to reach durable storage </para></entry> </row> + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>parallel_workers_to_launch</structfield> <type>bigint</type> + </para> + <para> + Number of parallel workers planned to be launched by queries on this database + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>parallel_workers_launched</structfield> <type>bigint</type> + </para> + <para> + Number of parallel workers launched by queries on this database + </para></entry> + </row> + <row> <entry role="catalog_table_entry"><para role="column_definition"> <structfield>stats_reset</structfield> <type>timestamp with time zone</type> -- 2.45.2
signature.asc
Description: PGP signature