On 10/11/24 09:33, Guillaume Lelarge wrote:
FWIW, with the recent commits of the pg_stat_statements patch, you need a slight change in the patch I sent on this thread. You'll find a patch attached to do that. You need to apply it after a rebase to master.

Thanks.

Here is an updated version, I modified it to:

* have the same wording in the doc and code (planned => to_launch)
* split de declaration from the rest (and have the same code as the parallel worker logging patch)

--
Benoit Lobréau
Consultant
http://dalibo.com
From ab9aa1344f974348638dd3898c944f3d5253374d Mon Sep 17 00:00:00 2001
From: benoit <benoit.lobr...@dalibo.com>
Date: Tue, 8 Oct 2024 10:01:52 +0200
Subject: [PATCH 3/3] Adds two parallel workers stat columns for utilities to
 pg_stat_database

* parallel_maint_workers_to_launch
* parallel_maint_workers_launched
---
 doc/src/sgml/monitoring.sgml                  | 18 ++++++++++++++++++
 src/backend/access/brin/brin.c                |  4 ++++
 src/backend/access/nbtree/nbtsort.c           |  4 ++++
 src/backend/catalog/system_views.sql          |  2 ++
 src/backend/commands/vacuumparallel.c         |  6 ++++++
 src/backend/utils/activity/pgstat_database.c  | 18 ++++++++++++++++++
 src/backend/utils/adt/pgstatfuncs.c           |  6 ++++++
 src/include/catalog/pg_proc.dat               | 10 ++++++++++
 src/include/pgstat.h                          |  3 +++
 src/test/regress/expected/rules.out           |  2 ++
 src/test/regress/expected/vacuum_parallel.out | 19 +++++++++++++++++++
 src/test/regress/sql/vacuum_parallel.sql      | 11 +++++++++++
 12 files changed, 103 insertions(+)

diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 840d7f8161..bd4e4b63c7 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -3629,6 +3629,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_maint_workers_to_launch</structfield> <type>bigint</type>
+      </para>
+      <para>
+       Number of parallel workers planned to be launched 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 launched 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 da9a8fe99f..648166bb3b 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1075,6 +1075,8 @@ CREATE VIEW pg_stat_database AS
             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_parallel_maint_workers_to_launch(D.oid) as parallel_maint_workers_to_launch,
+            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 77679e8df6..edd0823353 100644
--- a/src/backend/commands/vacuumparallel.c
+++ b/src/backend/commands/vacuumparallel.c
@@ -443,6 +443,12 @@ parallel_vacuum_end(ParallelVacuumState *pvs, IndexBulkDeleteResult **istats)
 {
 	Assert(!IsParallelWorker());
 
+	if (pvs->nworkers_to_launch > 0)
+		pgstat_update_parallel_maint_workers_stats(
+			(PgStat_Counter) pvs->pcxt->nworkers_to_launch,
+			(PgStat_Counter) pvs->pcxt->nworkers_launched
+		);
+
 	/* Copy the updated statistics */
 	for (int i = 0; i < pvs->nindexes; i++)
 	{
diff --git a/src/backend/utils/activity/pgstat_database.c b/src/backend/utils/activity/pgstat_database.c
index efa3d51408..38daf6d978 100644
--- a/src/backend/utils/activity/pgstat_database.c
+++ b/src/backend/utils/activity/pgstat_database.c
@@ -278,6 +278,22 @@ pgstat_update_parallel_workers_stats(PgStat_Counter parallel_workers_to_launch,
 	dbentry->parallel_workers_launched += parallel_workers_launched;
 }
 
+/*
+ * reports parallel_maint_workers_to_launch and parallel_maint_workers_launched into
+ * PgStat_StatDBEntry
+ */
+void
+pgstat_update_parallel_maint_workers_stats(PgStat_Counter parallel_maint_workers_to_launch, PgStat_Counter parallel_maint_workers_launched)
+{
+	PgStat_StatDBEntry *dbentry;
+	if (!OidIsValid(MyDatabaseId))
+		return;
+
+	dbentry = pgstat_prep_database_pending(MyDatabaseId);
+	dbentry->parallel_maint_workers_to_launch += parallel_maint_workers_to_launch;
+	dbentry->parallel_maint_workers_launched += parallel_maint_workers_launched;
+}
+
 /*
  * Subroutine for pgstat_report_stat(): Handle xact commit/rollback and I/O
  * timings.
@@ -443,6 +459,8 @@ pgstat_database_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
 	PGSTAT_ACCUM_DBCOUNT(sessions_killed);
 	PGSTAT_ACCUM_DBCOUNT(parallel_workers_to_launch);
 	PGSTAT_ACCUM_DBCOUNT(parallel_workers_launched);
+	PGSTAT_ACCUM_DBCOUNT(parallel_maint_workers_to_launch);
+	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 054c416ab4..13d5ea7a5c 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1045,6 +1045,12 @@ 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_parallel_maint_workers_to_launch*/
+PG_STAT_GET_DBENTRY_INT64(parallel_maint_workers_to_launch)
+
+/* 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 fe05b279f2..16cb46f343 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5820,6 +5820,16 @@
   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 to be launched for utilities',
+  proname => 'pg_stat_get_db_parallel_maint_workers_to_launch', provolatile => 's',
+  proparallel => 'r', prorettype => 'int8', proargtypes => 'oid',
+  prosrc => 'pg_stat_get_db_parallel_maint_workers_to_launch' },
+{ 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 cfba5615a7..3718d31cf6 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -389,6 +389,8 @@ typedef struct PgStat_StatDBEntry
 
 	PgStat_Counter parallel_workers_to_launch;
 	PgStat_Counter parallel_workers_launched;
+	PgStat_Counter parallel_maint_workers_to_launch;
+	PgStat_Counter parallel_maint_workers_launched;
 
 	TimestampTz stat_reset_timestamp;
 } PgStat_StatDBEntry;
@@ -587,6 +589,7 @@ 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_to_launch, PgStat_Counter parallel_workers_launched);
+extern void pgstat_update_parallel_maint_workers_stats(PgStat_Counter parallel_maint_workers_to_launch, 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 3014d047fe..e696baa8f3 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1865,6 +1865,8 @@ pg_stat_database| SELECT oid AS datid,
     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_parallel_maint_workers_to_launch(oid) AS parallel_maint_workers_to_launch,
+    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/vacuum_parallel.out b/src/test/regress/expected/vacuum_parallel.out
index ddf0ee544b..4973c7bdae 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_to_launch) AS parallel_maint_workers_to_launch_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_to_launch) > :'parallel_maint_workers_to_launch_before' AS maint_wrk_to_launch,
+       sum(parallel_maint_workers_launched) > :'parallel_maint_workers_launched_before' AS maint_wrk_launched
+FROM pg_stat_database;
+ maint_wrk_to_launch | 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/vacuum_parallel.sql b/src/test/regress/sql/vacuum_parallel.sql
index 1d23f33e39..77ddc807cd 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_to_launch) AS parallel_maint_workers_to_launch_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_to_launch) > :'parallel_maint_workers_to_launch_before' AS maint_wrk_to_launch,
+       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

From d3319375a66bc9e356c8ad741f047d82a47255e3 Mon Sep 17 00:00:00 2001
From: benoit <benoit.lobr...@dalibo.com>
Date: Fri, 11 Oct 2024 23:56:23 +0200
Subject: [PATCH 2/3] Setup counters for parallel vacuums

This is used by the logging and  pg_stat_database patches.
---
 src/backend/commands/vacuumparallel.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c
index 4fd6574e12..77679e8df6 100644
--- a/src/backend/commands/vacuumparallel.c
+++ b/src/backend/commands/vacuumparallel.c
@@ -208,6 +208,9 @@ struct ParallelVacuumState
 	int			nindexes_parallel_cleanup;
 	int			nindexes_parallel_condcleanup;
 
+	int			nworkers_to_launch;
+	int			nworkers_launched;
+
 	/* Buffer access strategy used by leader process */
 	BufferAccessStrategy bstrategy;
 
@@ -362,6 +365,9 @@ parallel_vacuum_init(Relation rel, Relation *indrels, int nindexes,
 		if ((vacoptions & VACUUM_OPTION_PARALLEL_COND_CLEANUP) != 0)
 			pvs->nindexes_parallel_condcleanup++;
 	}
+	pvs->nworkers_to_launch = 0;
+	pvs->nworkers_launched = 0;
+
 	shm_toc_insert(pcxt->toc, PARALLEL_VACUUM_KEY_INDEX_STATS, indstats);
 	pvs->indstats = indstats;
 
@@ -739,6 +745,9 @@ 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]);
+
+		pvs->nworkers_to_launch += pvs->pcxt->nworkers_to_launch;
+		pvs->nworkers_launched += pvs->pcxt->nworkers_launched;
 	}
 
 	/*
-- 
2.46.2

From f759381fdd2315b9fc3bf7c31f505f80f89a5d90 Mon Sep 17 00:00:00 2001
From: benoit <benoit.lobr...@dalibo.com>
Date: Fri, 11 Oct 2024 17:29:13 +0200
Subject: [PATCH 1/3] Adds two parallel workers stat columns to
 pg_stat_database

* parallel_workers_to_launch
* parallel_workers_launched
---
 doc/src/sgml/monitoring.sgml                  | 18 +++++++++++++
 src/backend/catalog/system_views.sql          |  2 ++
 src/backend/executor/execMain.c               |  6 +++++
 src/backend/utils/activity/pgstat_database.c  | 18 +++++++++++++
 src/backend/utils/adt/pgstatfuncs.c           |  6 +++++
 src/include/catalog/pg_proc.dat               | 10 +++++++
 src/include/pgstat.h                          |  4 +++
 src/test/regress/expected/rules.out           |  2 ++
 src/test/regress/expected/select_parallel.out | 26 +++++++++++++++++++
 src/test/regress/sql/select_parallel.sql      | 13 ++++++++++
 10 files changed, 105 insertions(+)

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>
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..e3da94cb10 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,11 @@ 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..efa3d51408 100644
--- a/src/backend/utils/activity/pgstat_database.c
+++ b/src/backend/utils/activity/pgstat_database.c
@@ -262,6 +262,22 @@ AtEOXact_PgStat_Database(bool isCommit, bool parallel)
 	}
 }
 
+/*
+ * reports parallel_workers_to_launch and parallel_workers_launched into
+ * PgStat_StatDBEntry
+ */
+void
+pgstat_update_parallel_workers_stats(PgStat_Counter parallel_workers_to_launch, PgStat_Counter parallel_workers_launched)
+{
+	PgStat_StatDBEntry *dbentry;
+	if (!OidIsValid(MyDatabaseId))
+		return;
+
+	dbentry = pgstat_prep_database_pending(MyDatabaseId);
+	dbentry->parallel_workers_to_launch += parallel_workers_to_launch;
+	dbentry->parallel_workers_launched += parallel_workers_launched;
+}
+
 /*
  * Subroutine for pgstat_report_stat(): Handle xact commit/rollback and I/O
  * timings.
@@ -425,6 +441,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..054c416ab4 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/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 8876bebde0..fe05b279f2 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5810,6 +5810,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 for 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 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 => '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..cfba5615a7 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -387,6 +387,9 @@ typedef struct PgStat_StatDBEntry
 	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 +586,7 @@ 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_to_launch, PgStat_Counter parallel_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..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..d1bb0bd61a 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_to_launch as parallel_workers_to_launch_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;
@@ -1407,3 +1418,18 @@ CREATE UNIQUE INDEX parallel_hang_idx
 SET debug_parallel_query = on;
 DELETE FROM parallel_hang WHERE 380 <= i AND i <= 420;
 ROLLBACK;
+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 = 'regression';
+ 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..5da7d6bcc8 100644
--- a/src/test/regress/sql/select_parallel.sql
+++ b/src/test/regress/sql/select_parallel.sql
@@ -2,6 +2,13 @@
 -- PARALLEL
 --
 
+-- Get a reference for parallel stats in pg_stat_database
+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 = 'regression' \gset
+
 create function sp_parallel_restricted(int) returns int as
   $$begin return $1; end$$ language plpgsql parallel restricted;
 
@@ -574,3 +581,9 @@ SET debug_parallel_query = on;
 DELETE FROM parallel_hang WHERE 380 <= i AND i <= 420;
 
 ROLLBACK;
+
+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 = 'regression';
-- 
2.46.2

Reply via email to