Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wWcZJ-002k5f-2m for pgsql-hackers@arkaria.postgresql.org; Mon, 08 Jun 2026 16:11:18 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wWcZI-003Al0-2g for pgsql-hackers@arkaria.postgresql.org; Mon, 08 Jun 2026 16:11:16 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wWcZH-003AkZ-2r for pgsql-hackers@lists.postgresql.org; Mon, 08 Jun 2026 16:11:16 +0000 Received: from fhigh-b7-smtp.messagingengine.com ([202.12.124.158]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1wWcZC-00000001zxj-3vF5 for pgsql-hackers@postgresql.org; Mon, 08 Jun 2026 16:11:15 +0000 Received: from phl-compute-06.internal (phl-compute-06.internal [10.202.2.46]) by mailfhigh.stl.internal (Postfix) with ESMTP id B2B1B7A0116; Mon, 8 Jun 2026 12:11:07 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-06.internal (MEProxy); Mon, 08 Jun 2026 12:11:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kurilemu.de; h= cc:cc:content-transfer-encoding:content-type:content-type:date :date:from:from:in-reply-to:in-reply-to:message-id:mime-version :reply-to:subject:subject:to:to; s=fm2; t=1780935067; x= 1781021467; bh=er6DtsUFNsL/QlCQoz2rPJGgxwd/TuPDwc6TaIkGTbM=; b=H 5Jb64ii0L9orowWrZsKlv5x0voni6+TBNaoRvxt1d/9wBWAaizl9CGTJ+Uh24ZZn YWARfr3g/nN10EcR3OSyVzy7AomlvutAyXIfHBsP8PFk1mnnZZZq5gn1pNZqM1YR DNMmBdW3ZSloxZXKZHGe4H60Imjr9Ev1PXU8JP1doSZl27si1aqgRrM+msCsO3DK zeJyDDIT+MyYBhOWLWuzt3sDDeVklUvAQia4820WkW8HgKuJStHBSMb4ZypEsZZJ TvmB347XUjs6Dr7u79cTcxRv94Te3oRRSXI8mCBf5EkOEnXhhCW3Kp+w0OuA9OrI obvwvpywZjDFrubQhBVtA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; t=1780935067; x=1781021467; bh=e r6DtsUFNsL/QlCQoz2rPJGgxwd/TuPDwc6TaIkGTbM=; b=RRyPfa11HO0TzSsWE 1pwwicZTHTkK1H+bRoQ/GYlkML2Sbp1HURpXIasIm7KqSBZn5r/AY8iNuxDZc+9B OHC3N/qc5LFQ+xyTEkcw+gsdtyrdQvHJGfl7+EXy6TZZL6CISEOHYzn2NoXGsQUX QTEqlAMB0nUdhhnT0QU/dGtJOLWQrVXU5p2vP77d/zk404oCa+uNMD0YmKtsBAuc LV2FYdERfm9ismuGpUkVTQHr0rzLkS9C/nwErbi7jfdln/JWxIUvbZgDaaaNukXQ Bo0/E6Cd6GjoMo4sCmwPYzdaw5fsCe71QPuYSQ30gFPaHeoxbVhLC+nlpzrxEAxm WkCzA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTGU0JPs5d+WzQV3kdEeYSC73az6/rAdh/0N11GgIanfm/DXWVbJTjAAHE63PXcSfT jj+dZzzqoGxcZMC6Aj1zoRWGxv1Cpy2SpndMIgeWsVst8q4O4A+MDmmmFSi8qBO0pnHPgu 3kbZICxOaAzcLGFEJ0L1SjWhEf+CqjkJW7xUdoAQnxlZTZKk8hc4lBrA94sj3PpGk504v/ NwAO9YvlzNqlP0+3T3Gb+3yieBfsCscMG0Y0My5U7Sq7PsEfg9ePBJ/xtIEKFRleSM6sB+ I7AA8ZgGZfzWG8tl5o18Yfg2vtkEXV2vIJdzflic5KM6Y3Brr7Y0m2865RelSn9dUIDygl mVzBgs9Wh/jKg3Prz3Nm/C7MxPL269Wkxhu8+H3LwXt9qC3hhvi/Po6fwwm7ky2sXwDPix 1H8qfddOAS8lrFtIIbg3GfmCUdTiogSyVcs3AdS5yFqrBw8yhNnOBb1O2wqUrTNsTZqW9h +4XFnVA7g7bYCT8eFvJIF+lMIJI9Zg+jAozSKk46X0yjjghRtMhLf4o+NxcW73vsXdalWi laIov91oPfm1Ls7SKT/TpuLjv+au9RAswNh6mwZpHsbxwXoBnG84ix8oU+aOuAK6uq1sWm As0/3Yur7kuXPaa1/hkKYliXqyZsgUno2xOAQqisA9GQijEOj2mheYG/vf5Q X-ME-Proxy: Feedback-ID: ie3de48e3:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 8 Jun 2026 12:11:06 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kurilemu.de; s=schmee; t=1780935062; bh=6n30tNhbVMuA3eCbwogLNRNAq6CmMs4Qnx7BnTTzjA4=; h=Date:From:To:Cc:Subject:In-Reply-To:From; b=c/8nkXCPrYNDPQYhAMqd0gO4pQWGmGWuOHrmNBWX/cxRfT8mao1lvRfrVXVkHFULM Iy71EYfft/P8pY3Xuo9hRwkNzRNuMS220GtRbO/CJ0Er0lbTX7wnwLxXVubFWsTTap dGG9sPnFpC1eKqF9R5LOgPvV5/lO8Te4SlVWIm3++7jAKvTlnqsdRo1dXFSJCXMkYS dPJ9KQJDyxqT97t952yZ0H5j04fN3t76kD8DtB4Q28gYWnUys5e+dv4gBTGgbKeiIq 6QF0SPtgWRzsx3LmHq5CMHqMSBMcHMAry1nCb8pLEOHOGTQ2JLQx+Ztt7xxwNtTNUA rJMsby1xbX5Yw== Received: by ida.kurilemu.internal (Postfix, from userid 1000) id 73D7AB0065B; Mon, 08 Jun 2026 18:11:02 +0200 (CEST) Date: Mon, 8 Jun 2026 18:11:02 +0200 From: =?utf-8?Q?=C3=81lvaro?= Herrera To: solai v Cc: Benoit =?utf-8?Q?Lobr=C3=A9au?= , pgsql-hackers Subject: Re: Logging parallel worker draught Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="alfjcfchgbd4n3kz" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --alfjcfchgbd4n3kz Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2026-Jun-08, solai v wrote: > The patches applied cleanly, but PostgreSQL failed to build.The build > errors indicate that log_parallel_workers, > log_parallel_workers_options, LOG_PARALLEL_WORKERS_NONE, and > LogParallelWorkersIfNeeded() are referenced during compilation but > could not be found, Yeah, I think some hunks disappeared from 0001, in the .h files as well as the .sgml docs. Probably just a borked merge. I re-merged them, here's the patchset again. I did not review this. -- Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/ "El destino baraja y nosotros jugamos" (A. Schopenhauer) --alfjcfchgbd4n3kz Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=v11-0001-Add-a-guc-for-parallel-worker-logging.patch From b218e87a08acebf5fb5aea149b70c71c8fbd9872 Mon Sep 17 00:00:00 2001 From: benoit Date: Tue, 8 Oct 2024 12:39:41 +0200 Subject: [PATCH v11 1/3] Add a guc for parallel worker logging The new guc log_parallel_workers controls whether a log message is produced to display information on the number of workers spawned when a parallel query or utility is executed. The default value is `none` which disables logging. `all` displays information for all parallel queries, whereas `shortage` displays information only when the number of workers launched is lower than the number of planned workers. This new parameter can help database administrators and developers diagnose performance issues related to parallelism and optimize the configuration of the system accordingly. --- doc/src/sgml/config.sgml | 18 ++++++++++++++++++ src/backend/access/transam/parallel.c | 19 +++++++++++++++++++ src/backend/utils/misc/guc_parameters.dat | 8 ++++++++ src/backend/utils/misc/guc_tables.c | 8 ++++++++ src/backend/utils/misc/postgresql.conf.sample | 1 + src/include/access/parallel.h | 11 +++++++++++ src/include/utils/guc.h | 1 + 7 files changed, 66 insertions(+) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index fa566c9e553..97957b34eb7 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -8404,6 +8404,24 @@ log_line_prefix = '%m [%p] %q%u@%d/%a ' + + log_parallel_workers (enum) + + log_parallel_workers configuration parameter + + + + + Controls whether a log message about the number of workers is emitted during the + execution of a parallel query or utility statement. The default value is + none which disables logging. all emits + information for all parallel queries or utilities, whereas shortage + emits information only when the number of workers launched is lower than the number + of planned workers. + + + + log_parameter_max_length (integer) diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index 89e9d224eec..be0531ad4bb 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -1671,3 +1671,22 @@ LookupParallelWorkerFunction(const char *libraryname, const char *funcname) return (parallel_worker_main_type) load_external_function(libraryname, funcname, true, NULL); } + +/* + * If required, emit information about parallel workers usage in + * the logs. + */ +void +LogParallelWorkersIfNeeded(int log_parallel_workers, + int parallel_workers_to_launch, + int parallel_workers_launched) +{ + if ((log_parallel_workers == LOG_PARALLEL_WORKERS_ALL && + parallel_workers_to_launch > 0) || + (log_parallel_workers == LOG_PARALLEL_WORKERS_SHORTAGE && + parallel_workers_to_launch != parallel_workers_launched)) + ereport(LOG, + (errmsg("launched %i parallel workers (planned: %i)", + parallel_workers_launched, + parallel_workers_to_launch))); +} diff --git a/src/backend/utils/misc/guc_parameters.dat b/src/backend/utils/misc/guc_parameters.dat index afaa058b046..807cee3135c 100644 --- a/src/backend/utils/misc/guc_parameters.dat +++ b/src/backend/utils/misc/guc_parameters.dat @@ -1786,6 +1786,14 @@ assign_hook => 'assign_log_min_messages', }, +{ name => 'log_parallel_workers', type => 'enum', context => 'PGC_SUSET', group => 'LOGGING_WHAT', + short_desc => 'Log information about parallel worker usage.', + long_desc => '"none" doesn\'t log anything, "all" logs all parallel worker usage and "shortage" logs only when the planned workers couldn\'t be acquired', + variable => 'log_parallel_workers', + boot_val => 'LOG_PARALLEL_WORKERS_NONE', + options => 'log_parallel_workers_options', +}, + { name => 'log_parameter_max_length', type => 'int', context => 'PGC_SUSET', group => 'LOGGING_WHAT', short_desc => 'Sets the maximum length in bytes of data logged for bind parameter values when logging statements.', long_desc => '-1 means log values in full.', diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 290ccbc543e..429a2d6e4d0 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -31,6 +31,7 @@ #include "access/commit_ts.h" #include "access/gin.h" +#include "access/parallel.h" #include "access/slru.h" #include "access/toast_compression.h" #include "access/twophase.h" @@ -516,6 +517,12 @@ static const struct config_enum_entry data_checksums_options[] = { {"off", PG_DATA_CHECKSUM_OFF, true}, {"inprogress-on", PG_DATA_CHECKSUM_INPROGRESS_ON, true}, {"inprogress-off", PG_DATA_CHECKSUM_INPROGRESS_OFF, true}, +}; + +static const struct config_enum_entry log_parallel_workers_options[] = { + {"none", LOG_PARALLEL_WORKERS_NONE, false}, + {"all", LOG_PARALLEL_WORKERS_ALL, false}, + {"shortage", LOG_PARALLEL_WORKERS_SHORTAGE, false}, {NULL, 0, false} }; @@ -571,6 +578,7 @@ int log_min_duration_statement = -1; int log_parameter_max_length = -1; int log_parameter_max_length_on_error = 0; int log_temp_files = -1; +int log_parallel_workers = LOG_PARALLEL_WORKERS_NONE; double log_statement_sample_rate = 1.0; double log_xact_sample_rate = 0; char *backtrace_functions; diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index ac38cddaaf9..222cf6b3048 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -679,6 +679,7 @@ #log_temp_files = -1 # log temporary files equal or larger # than the specified size in kilobytes; # -1 disables, 0 logs all temp files +#log_parallel_workers = none # none, all, shortage #log_timezone = 'GMT' # - Process Title - diff --git a/src/include/access/parallel.h b/src/include/access/parallel.h index 60f857675e0..6cd42358daf 100644 --- a/src/include/access/parallel.h +++ b/src/include/access/parallel.h @@ -55,6 +55,13 @@ typedef struct ParallelWorkerContext shm_toc *toc; } ParallelWorkerContext; +typedef enum +{ + LOG_PARALLEL_WORKERS_NONE = 0, + LOG_PARALLEL_WORKERS_ALL, + LOG_PARALLEL_WORKERS_SHORTAGE, +} log_parallel_workers_option_list; + extern PGDLLIMPORT volatile sig_atomic_t ParallelMessagePending; extern PGDLLIMPORT int ParallelWorkerNumber; extern PGDLLIMPORT bool InitializingParallelWorker; @@ -80,4 +87,8 @@ extern void ParallelWorkerReportLastRecEnd(XLogRecPtr last_xlog_end); extern void ParallelWorkerMain(Datum main_arg); +extern void LogParallelWorkersIfNeeded(int log_parallel_workers, + int parallel_workers_to_launch, + int parallel_workers_launched); + #endif /* PARALLEL_H */ diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index dc406d6651a..41d0790a9c9 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -303,6 +303,7 @@ extern PGDLLIMPORT int log_temp_files; extern PGDLLIMPORT double log_statement_sample_rate; extern PGDLLIMPORT double log_xact_sample_rate; extern PGDLLIMPORT char *backtrace_functions; +extern PGDLLIMPORT int log_parallel_workers; extern PGDLLIMPORT int temp_file_limit; -- 2.47.3 --alfjcfchgbd4n3kz Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=v11-0002-Implements-logging-for-parallel-worker-usage-in-.patch From 309777539ec793e6efb3de8b62d41d7cb8ba0e48 Mon Sep 17 00:00:00 2001 From: benoit Date: Wed, 29 Jan 2025 17:10:57 +0100 Subject: [PATCH v11 2/3] Implements logging for parallel worker usage in utilities This patch implements logging of parallel worker usage for: * the index cleanup and bulkdelete phases of vacuum; * btree, brin and gin index builds. --- src/backend/access/brin/brin.c | 4 ++++ src/backend/access/gin/gininsert.c | 4 ++++ src/backend/access/nbtree/nbtsort.c | 4 ++++ src/backend/commands/vacuumparallel.c | 13 +++++++++++++ 4 files changed, 25 insertions(+) diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index bdb30752e09..3bb04c117d8 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -2568,6 +2568,10 @@ _brin_end_parallel(BrinLeader *brinleader, BrinBuildState *state) /* Shutdown worker processes */ WaitForParallelWorkersToFinish(brinleader->pcxt); + LogParallelWorkersIfNeeded(log_parallel_workers, + brinleader->pcxt->nworkers_to_launch, + 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/gin/gininsert.c b/src/backend/access/gin/gininsert.c index cb9ed3b563c..c752cea8c60 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -1120,6 +1120,10 @@ _gin_end_parallel(GinLeader *ginleader, GinBuildState *state) /* Shutdown worker processes */ WaitForParallelWorkersToFinish(ginleader->pcxt); + LogParallelWorkersIfNeeded(log_parallel_workers, + ginleader->pcxt->nworkers_to_launch, + ginleader->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 756dfa3dcf4..2670e88cd22 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); + LogParallelWorkersIfNeeded(log_parallel_workers, + btleader->pcxt->nworkers_to_launch, + 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/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c index 41cefcfde54..611d67154b9 100644 --- a/src/backend/commands/vacuumparallel.c +++ b/src/backend/commands/vacuumparallel.c @@ -257,6 +257,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; @@ -424,6 +427,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; @@ -516,6 +522,10 @@ parallel_vacuum_end(ParallelVacuumState *pvs, IndexBulkDeleteResult **istats) { Assert(!IsParallelWorker()); + LogParallelWorkersIfNeeded(log_parallel_workers, + pvs->nworkers_to_launch, + pvs->nworkers_launched); + /* Copy the updated statistics */ for (int i = 0; i < pvs->nindexes; i++) { @@ -946,6 +956,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.47.3 --alfjcfchgbd4n3kz Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=v11-0003-Implements-logging-for-parallel-worker-usage-in-.patch From 6097a014f688be508855afe62c8cc2209e35221e Mon Sep 17 00:00:00 2001 From: benoit Date: Wed, 29 Jan 2025 17:15:25 +0100 Subject: [PATCH v11 3/3] Implements logging for parallel worker usage in queries --- src/backend/executor/execMain.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 4b30f768680..3ff7a629573 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -499,6 +499,10 @@ standard_ExecutorEnd(QueryDesc *queryDesc) pgstat_update_parallel_workers_stats((PgStat_Counter) estate->es_parallel_workers_to_launch, (PgStat_Counter) estate->es_parallel_workers_launched); + LogParallelWorkersIfNeeded(log_parallel_workers, + estate->es_parallel_workers_to_launch, + 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 -- 2.47.3 --alfjcfchgbd4n3kz--