Hey, Le mer. 2 oct. 2024 à 11:12, Benoit Lobréau <benoit.lobr...@dalibo.com> a écrit :
> Hi, > > Thanks for your imput ! I will fix the doc as proposed and do the split > as soon as I have time. > > I've done the split, but I didn't go any further than that. Two patches attached: * v5-0001 adds the metrics (same patch than v3-0001 for pg_stat_statements) * v5-0002 handles the metrics for pg_stat_database. "make check" works, and I also did a few other tests without any issues. Regards. -- Guillaume.
From 9413829616bdc0806970647c15d7d6bbd96489d1 Mon Sep 17 00:00:00 2001 From: Guillaume Lelarge <guillaume.lela...@dalibo.com> Date: Mon, 7 Oct 2024 08:45:36 +0200 Subject: [PATCH v5 1/2] Introduce two new counters in EState They will be used by two other patchs to populate new columns in pg_stat_database and pg_statements. --- src/backend/executor/execUtils.c | 3 +++ src/backend/executor/nodeGather.c | 3 +++ src/backend/executor/nodeGatherMerge.c | 3 +++ src/include/nodes/execnodes.h | 3 +++ 4 files changed, 12 insertions(+) diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 5737f9f4eb..1908481999 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -162,6 +162,9 @@ CreateExecutorState(void) estate->es_jit_flags = 0; estate->es_jit = NULL; + estate->es_parallelized_workers_launched = 0; + estate->es_parallelized_workers_planned = 0; + /* * Return the executor state structure */ diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c index 5d4ffe989c..0fb915175a 100644 --- a/src/backend/executor/nodeGather.c +++ b/src/backend/executor/nodeGather.c @@ -182,6 +182,9 @@ ExecGather(PlanState *pstate) /* We save # workers launched for the benefit of EXPLAIN */ node->nworkers_launched = pcxt->nworkers_launched; + estate->es_parallelized_workers_launched += pcxt->nworkers_launched; + estate->es_parallelized_workers_planned += pcxt->nworkers_to_launch; + /* Set up tuple queue readers to read the results. */ if (pcxt->nworkers_launched > 0) { diff --git a/src/backend/executor/nodeGatherMerge.c b/src/backend/executor/nodeGatherMerge.c index 45f6017c29..149ab23d90 100644 --- a/src/backend/executor/nodeGatherMerge.c +++ b/src/backend/executor/nodeGatherMerge.c @@ -223,6 +223,9 @@ ExecGatherMerge(PlanState *pstate) /* We save # workers launched for the benefit of EXPLAIN */ node->nworkers_launched = pcxt->nworkers_launched; + estate->es_parallelized_workers_launched += pcxt->nworkers_launched; + estate->es_parallelized_workers_planned += pcxt->nworkers_to_launch; + /* Set up tuple queue readers to read the results. */ if (pcxt->nworkers_launched > 0) { diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index aab59d681c..f898590ece 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -708,6 +708,9 @@ typedef struct EState bool es_use_parallel_mode; /* can we use parallel workers? */ + int es_parallelized_workers_launched; + int es_parallelized_workers_planned; + /* The per-query shared memory area to use for parallel execution. */ struct dsa_area *es_query_dsa; -- 2.46.2
From 873c03b99e1ccc05bac4c71b5f070e0dbe0bd779 Mon Sep 17 00:00:00 2001 From: benoit <benoit.lobr...@dalibo.com> Date: Mon, 7 Oct 2024 10:12:46 +0200 Subject: [PATCH v5 2/2] Adds four parallel workers stat columns to pg_stat_database * parallel_workers_planned * parallel_workers_launched * parallel_maint_workers_planned * parallel_maint_workers_launched --- doc/src/sgml/monitoring.sgml | 36 +++++++++++++++++++ src/backend/access/brin/brin.c | 4 +++ src/backend/access/nbtree/nbtsort.c | 4 +++ src/backend/catalog/system_views.sql | 4 +++ src/backend/commands/vacuumparallel.c | 5 +++ src/backend/executor/execMain.c | 7 ++++ src/backend/utils/activity/pgstat_database.c | 36 +++++++++++++++++++ src/backend/utils/adt/pgstatfuncs.c | 12 +++++++ src/include/catalog/pg_proc.dat | 20 +++++++++++ src/include/pgstat.h | 7 ++++ src/test/regress/expected/rules.out | 4 +++ src/test/regress/expected/select_parallel.out | 11 ++++++ src/test/regress/expected/vacuum_parallel.out | 19 ++++++++++ src/test/regress/sql/select_parallel.sql | 8 +++++ src/test/regress/sql/vacuum_parallel.sql | 11 ++++++ 15 files changed, 188 insertions(+) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 331315f8d3..9567ca5bd1 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -3611,6 +3611,42 @@ 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_planned</structfield> <type>bigint</type> + </para> + <para> + Number of parallel workers planned 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 obtained by queries on this database + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>parallel_maint_workers_planned</structfield> <type>bigint</type> + </para> + <para> + Number of parallel workers planned by utilities on this database + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>parallel_maint_workers_launched</structfield> <type>bigint</type> + </para> + <para> + Number of parallel workers obtained by utilities 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> diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index c0b978119a..4e83091d2c 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -2544,6 +2544,10 @@ _brin_end_parallel(BrinLeader *brinleader, BrinBuildState *state) /* Shutdown worker processes */ WaitForParallelWorkersToFinish(brinleader->pcxt); + pgstat_update_parallel_maint_workers_stats( + (PgStat_Counter) brinleader->pcxt->nworkers_to_launch, + (PgStat_Counter) brinleader->pcxt->nworkers_launched); + /* * Next, accumulate WAL usage. (This must wait for the workers to finish, * or we might get incomplete data.) diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index 5cca0d4f52..8ee5fcf6d3 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -1615,6 +1615,10 @@ _bt_end_parallel(BTLeader *btleader) /* Shutdown worker processes */ WaitForParallelWorkersToFinish(btleader->pcxt); + pgstat_update_parallel_maint_workers_stats( + (PgStat_Counter) btleader->pcxt->nworkers_to_launch, + (PgStat_Counter) btleader->pcxt->nworkers_launched); + /* * Next, accumulate WAL usage. (This must wait for the workers to finish, * or we might get incomplete data.) diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 3456b821bc..7e693a5bae 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -1073,6 +1073,10 @@ 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_planned(D.oid) as parallel_workers_planned, + pg_stat_get_db_parallel_workers_launched(D.oid) as parallel_workers_launched, + pg_stat_get_db_parallel_maint_workers_planned(D.oid) as parallel_maint_workers_planned, + pg_stat_get_db_parallel_maint_workers_launched(D.oid) as parallel_maint_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/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c index 4fd6574e12..c6f43419aa 100644 --- a/src/backend/commands/vacuumparallel.c +++ b/src/backend/commands/vacuumparallel.c @@ -739,6 +739,11 @@ parallel_vacuum_process_all_indexes(ParallelVacuumState *pvs, int num_index_scan for (int i = 0; i < pvs->pcxt->nworkers_launched; i++) InstrAccumParallelQuery(&pvs->buffer_usage[i], &pvs->wal_usage[i]); + + pgstat_update_parallel_maint_workers_stats( + (PgStat_Counter) pvs->pcxt->nworkers_to_launch, + (PgStat_Counter) pvs->pcxt->nworkers_launched + ); } /* diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index cc9a594cba..e749cdaa17 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,12 @@ standard_ExecutorEnd(QueryDesc *queryDesc) Assert(estate != NULL); + if (estate->es_parallelized_workers_planned > 0) { + pgstat_update_parallel_workers_stats( + (PgStat_Counter) estate->es_parallelized_workers_planned, + (PgStat_Counter) estate->es_parallelized_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..9e72c286b2 100644 --- a/src/backend/utils/activity/pgstat_database.c +++ b/src/backend/utils/activity/pgstat_database.c @@ -262,6 +262,38 @@ AtEOXact_PgStat_Database(bool isCommit, bool parallel) } } +/* + * reports parallel_workers_planned and parallel_workers_launched into + * PgStat_StatDBEntry + */ +void +pgstat_update_parallel_workers_stats(PgStat_Counter parallel_workers_planned, PgStat_Counter parallel_workers_launched) +{ + PgStat_StatDBEntry *dbentry; + if (!OidIsValid(MyDatabaseId)) + return; + + dbentry = pgstat_prep_database_pending(MyDatabaseId); + dbentry->parallel_workers_planned += parallel_workers_planned; + dbentry->parallel_workers_launched += parallel_workers_launched; +} + +/* + * reports parallel_maint_workers_planned and parallel_maint_workers_launched into + * PgStat_StatDBEntry + */ +void +pgstat_update_parallel_maint_workers_stats(PgStat_Counter parallel_maint_workers_planned, PgStat_Counter parallel_maint_workers_launched) +{ + PgStat_StatDBEntry *dbentry; + if (!OidIsValid(MyDatabaseId)) + return; + + dbentry = pgstat_prep_database_pending(MyDatabaseId); + dbentry->parallel_maint_workers_planned += parallel_maint_workers_planned; + dbentry->parallel_maint_workers_launched += parallel_maint_workers_launched; +} + /* * Subroutine for pgstat_report_stat(): Handle xact commit/rollback and I/O * timings. @@ -425,6 +457,10 @@ 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_planned); + PGSTAT_ACCUM_DBCOUNT(parallel_workers_launched); + PGSTAT_ACCUM_DBCOUNT(parallel_maint_workers_planned); + PGSTAT_ACCUM_DBCOUNT(parallel_maint_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..2db4d2bb6b 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -1039,6 +1039,18 @@ 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_planned*/ +PG_STAT_GET_DBENTRY_INT64(parallel_workers_planned) + +/* pg_stat_get_db_parallel_workers_launched*/ +PG_STAT_GET_DBENTRY_INT64(parallel_workers_launched) + +/* pg_stat_get_db_parallel_maint_workers_planned*/ +PG_STAT_GET_DBENTRY_INT64(parallel_maint_workers_planned) + +/* pg_stat_get_db_parallel_maint_workers_launched*/ +PG_STAT_GET_DBENTRY_INT64(parallel_maint_workers_launched) + /* pg_stat_get_db_temp_bytes */ PG_STAT_GET_DBENTRY_INT64(temp_bytes) diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 77f54a79e6..47dc0f87eb 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -5803,6 +5803,26 @@ 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 for queries', + proname => 'pg_stat_get_db_parallel_workers_planned', provolatile => 's', + proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_db_parallel_workers_planned' }, +{ oid => '8404', + descr => 'statistics: number of parallel workers effectively launched for 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 => '8405', + descr => 'statistics: number of parallel workers planned for utilities', + proname => 'pg_stat_get_db_parallel_maint_workers_planned', provolatile => 's', + proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_db_parallel_maint_workers_planned' }, +{ oid => '8406', + descr => 'statistics: number of parallel workers effectively launched for utilities', + proname => 'pg_stat_get_db_parallel_maint_workers_launched', provolatile => 's', + proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_db_parallel_maint_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..1a5c489bbd 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -387,6 +387,11 @@ typedef struct PgStat_StatDBEntry PgStat_Counter sessions_fatal; PgStat_Counter sessions_killed; + PgStat_Counter parallel_workers_planned; + PgStat_Counter parallel_workers_launched; + PgStat_Counter parallel_maint_workers_planned; + PgStat_Counter parallel_maint_workers_launched; + TimestampTz stat_reset_timestamp; } PgStat_StatDBEntry; @@ -583,6 +588,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 parallel_workers_planned, PgStat_Counter parallel_workers_launched); +extern void pgstat_update_parallel_maint_workers_stats(PgStat_Counter parallel_maint_workers_planned, PgStat_Counter parallel_maint_workers_launched); #define pgstat_count_buffer_read_time(n) \ (pgStatBlockReadTime += (n)) diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 2b47013f11..c795fb68c1 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1863,6 +1863,10 @@ 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_planned(oid) AS parallel_workers_planned, + pg_stat_get_db_parallel_workers_launched(oid) AS parallel_workers_launched, + pg_stat_get_db_parallel_maint_workers_planned(oid) AS parallel_maint_workers_planned, + pg_stat_get_db_parallel_maint_workers_launched(oid) AS parallel_maint_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 2c63aa85a6..db3ca8b198 100644 --- a/src/test/regress/expected/select_parallel.out +++ b/src/test/regress/expected/select_parallel.out @@ -1,6 +1,17 @@ -- -- PARALLEL -- +-- Get a reference for parallel stats in pg_stat_database +select pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +select parallel_workers_planned as parallel_workers_planned_before, + parallel_workers_launched as parallel_workers_launched_before +from pg_stat_database +where datname = 'regression' \gset create function sp_parallel_restricted(int) returns int as $$begin return $1; end$$ language plpgsql parallel restricted; begin; diff --git a/src/test/regress/expected/vacuum_parallel.out b/src/test/regress/expected/vacuum_parallel.out index ddf0ee544b..4c9c5cb1fd 100644 --- a/src/test/regress/expected/vacuum_parallel.out +++ b/src/test/regress/expected/vacuum_parallel.out @@ -37,9 +37,28 @@ WHERE oid in ('regular_sized_index'::regclass, 'typically_sized_index'::regclass 2 (1 row) +-- Get a reference for parallel stats in pg_stat_database +SELECT sum(parallel_maint_workers_planned) AS parallel_maint_workers_planned_before, + sum(parallel_maint_workers_launched) AS parallel_maint_workers_launched_before +FROM pg_stat_database \gset -- Parallel VACUUM with B-Tree page deletions, ambulkdelete calls: DELETE FROM parallel_vacuum_table; VACUUM (PARALLEL 4, INDEX_CLEANUP ON) parallel_vacuum_table; +-- Check parallel stats in pg_stat_database +SELECT pg_stat_force_next_flush(); + pg_stat_force_next_flush +-------------------------- + +(1 row) + +SELECT sum(parallel_maint_workers_planned) > :'parallel_maint_workers_planned_before' AS maint_wrk_planned, + sum(parallel_maint_workers_launched) > :'parallel_maint_workers_launched_before' AS maint_wrk_launched +FROM pg_stat_database; + maint_wrk_planned | maint_wrk_launched +-------------------+-------------------- + t | t +(1 row) + -- Since vacuum_in_leader_small_index uses deduplication, we expect an -- assertion failure with bug #17245 (in the absence of bugfix): INSERT INTO parallel_vacuum_table SELECT i FROM generate_series(1, 10000) i; diff --git a/src/test/regress/sql/select_parallel.sql b/src/test/regress/sql/select_parallel.sql index 9ba1328fd2..2ff0f7f21c 100644 --- a/src/test/regress/sql/select_parallel.sql +++ b/src/test/regress/sql/select_parallel.sql @@ -2,6 +2,14 @@ -- PARALLEL -- +-- Get a reference for parallel stats in pg_stat_database +select pg_stat_force_next_flush(); +select parallel_workers_planned as parallel_workers_planned_before, + parallel_workers_launched as parallel_workers_launched_before +from pg_stat_database +where datname = 'regression' \gset + + create function sp_parallel_restricted(int) returns int as $$begin return $1; end$$ language plpgsql parallel restricted; diff --git a/src/test/regress/sql/vacuum_parallel.sql b/src/test/regress/sql/vacuum_parallel.sql index 1d23f33e39..d0d7851e6a 100644 --- a/src/test/regress/sql/vacuum_parallel.sql +++ b/src/test/regress/sql/vacuum_parallel.sql @@ -31,10 +31,21 @@ WHERE oid in ('regular_sized_index'::regclass, 'typically_sized_index'::regclass pg_relation_size(oid) >= pg_size_bytes(current_setting('min_parallel_index_scan_size')); +-- Get a reference for parallel stats in pg_stat_database +SELECT sum(parallel_maint_workers_planned) AS parallel_maint_workers_planned_before, + sum(parallel_maint_workers_launched) AS parallel_maint_workers_launched_before +FROM pg_stat_database \gset + -- Parallel VACUUM with B-Tree page deletions, ambulkdelete calls: DELETE FROM parallel_vacuum_table; VACUUM (PARALLEL 4, INDEX_CLEANUP ON) parallel_vacuum_table; +-- Check parallel stats in pg_stat_database +SELECT pg_stat_force_next_flush(); +SELECT sum(parallel_maint_workers_planned) > :'parallel_maint_workers_planned_before' AS maint_wrk_planned, + sum(parallel_maint_workers_launched) > :'parallel_maint_workers_launched_before' AS maint_wrk_launched +FROM pg_stat_database; + -- Since vacuum_in_leader_small_index uses deduplication, we expect an -- assertion failure with bug #17245 (in the absence of bugfix): INSERT INTO parallel_vacuum_table SELECT i FROM generate_series(1, 10000) i; -- 2.46.2