On 09/06/2016 16:04, Robert Haas wrote:
>
> OK, I pushed this after re-reviewing it and fixing a number of
> oversights. There remains only the task of adding max_parallel_degree
> as a system-wide limit (as opposed to max_parallel_degree now
> max_parallel_workers_per_gather which is a per-Gather limit), which
> I'm going to argue should be a new open item and not necessarily one
> that I have to own myself. I would like to take care of it, but I
> will not put it ahead of fixing actual defects and I will not promise
> to have it done in time for 9.6.
>
PFA a patch to fix this open item. I used the GUC name provided in the
9.6 open item page (max_parallel_workers), with a default value of 4.
Value 0 is another way to disable parallel query.
--
Julien Rouhaud
http://dalibo.com - http://dalibo.org
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index e0e5a1e..c661c7a 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -2018,6 +2018,23 @@ include_dir 'conf.d'
</listitem>
</varlistentry>
+ <varlistentry id="guc-max-parallel-workers"
xreflabel="max_parallel_workers">
+ <term><varname>max_parallel_workers</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_parallel_workers</> configuration
parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the maximum number of workers that can be launched at the same
+ time for the whole server. This parameter allows the administrator to
+ reserve background worker slots for for third part dynamic background
+ workers. The default value is 4. Setting this value to 0 disables
+ parallel query execution.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="guc-backend-flush-after"
xreflabel="backend_flush_after">
<term><varname>backend_flush_after</varname> (<type>integer</type>)
<indexterm>
diff --git a/src/backend/access/transam/parallel.c
b/src/backend/access/transam/parallel.c
index ab5ef25..7b53b53 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -473,8 +473,8 @@ LaunchParallelWorkers(ParallelContext *pcxt)
{
memcpy(worker.bgw_extra, &i, sizeof(int));
if (!any_registrations_failed &&
- RegisterDynamicBackgroundWorker(&worker,
-
&pcxt->worker[i].bgwhandle))
+ RegisterDynamicBackgroundWorkerInternal(&worker,
+
&pcxt->worker[i].bgwhandle, true))
{
shm_mq_set_handle(pcxt->worker[i].error_mqh,
pcxt->worker[i].bgwhandle);
diff --git a/src/backend/optimizer/path/allpaths.c
b/src/backend/optimizer/path/allpaths.c
index cc8ba61..2bcd86b 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -719,9 +719,11 @@ create_plain_partial_paths(PlannerInfo *root, RelOptInfo
*rel)
}
/*
- * In no case use more than max_parallel_workers_per_gather workers.
+ * In no case use more than max_parallel_workers or
+ * max_parallel_workers_per_gather workers.
*/
- parallel_workers = Min(parallel_workers,
max_parallel_workers_per_gather);
+ parallel_workers = Min(max_parallel_workers, Min(parallel_workers,
+ max_parallel_workers_per_gather));
/* If any limit was set to zero, the user doesn't want a parallel scan.
*/
if (parallel_workers <= 0)
diff --git a/src/backend/optimizer/path/costsize.c
b/src/backend/optimizer/path/costsize.c
index e7f63f4..fd62126 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -113,6 +113,7 @@ int effective_cache_size =
DEFAULT_EFFECTIVE_CACHE_SIZE;
Cost disable_cost = 1.0e10;
+int max_parallel_workers = 4;
int max_parallel_workers_per_gather = 2;
bool enable_seqscan = true;
diff --git a/src/backend/optimizer/plan/planner.c
b/src/backend/optimizer/plan/planner.c
index 54c0440..81d124c 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -246,8 +246,9 @@ standard_planner(Query *parse, int cursorOptions,
ParamListInfo boundParams)
IsUnderPostmaster && dynamic_shared_memory_type !=
DSM_IMPL_NONE &&
parse->commandType == CMD_SELECT && !parse->hasModifyingCTE &&
parse->utilityStmt == NULL && max_parallel_workers_per_gather >
0 &&
- !IsParallelWorker() && !IsolationIsSerializable() &&
- !has_parallel_hazard((Node *) parse, true);
+ max_parallel_workers > 0 && !IsParallelWorker() &&
+ !IsolationIsSerializable() && !has_parallel_hazard((Node *)
parse,
+ true);
/*
* glob->parallelModeNeeded should tell us whether it's necessary to
diff --git a/src/backend/postmaster/bgworker.c
b/src/backend/postmaster/bgworker.c
index 382edad..71025b7 100644
--- a/src/backend/postmaster/bgworker.c
+++ b/src/backend/postmaster/bgworker.c
@@ -16,6 +16,7 @@
#include "miscadmin.h"
#include "libpq/pqsignal.h"
+#include "optimizer/cost.h"
#include "postmaster/bgworker_internals.h"
#include "postmaster/postmaster.h"
#include "storage/barrier.h"
@@ -76,6 +77,7 @@ typedef struct BackgroundWorkerSlot
bool terminate;
pid_t pid; /* InvalidPid = not started
yet; 0 = dead */
uint64 generation; /* incremented when slot is
recycled */
+ bool parallel;
BackgroundWorker worker;
} BackgroundWorkerSlot;
@@ -819,12 +821,14 @@ RegisterBackgroundWorker(BackgroundWorker *worker)
* free this pointer using pfree(), if desired.
*/
bool
-RegisterDynamicBackgroundWorker(BackgroundWorker *worker,
-
BackgroundWorkerHandle **handle)
+RegisterDynamicBackgroundWorkerInternal(BackgroundWorker *worker,
+
BackgroundWorkerHandle **handle,
+ bool parallel)
{
int slotno;
bool success = false;
uint64 generation = 0;
+ int n_active_parallel_workers = 0;
/*
* We can't register dynamic background workers from the postmaster. If
@@ -849,12 +853,22 @@ RegisterDynamicBackgroundWorker(BackgroundWorker *worker,
{
BackgroundWorkerSlot *slot =
&BackgroundWorkerData->slot[slotno];
- if (!slot->in_use)
+ if (slot->in_use && slot->parallel)
+ n_active_parallel_workers++;
+
+ /* In case of parallel worker, check if we didn't exhaust the
number of
+ * allowed parallel workers
+ */
+ if (parallel && n_active_parallel_workers >=
max_parallel_workers)
+ break;
+
+ if(!slot->in_use)
{
memcpy(&slot->worker, worker, sizeof(BackgroundWorker));
slot->pid = InvalidPid; /* indicates not
started yet */
slot->generation++;
slot->terminate = false;
+ slot->parallel = parallel;
generation = slot->generation;
/*
@@ -888,6 +902,14 @@ RegisterDynamicBackgroundWorker(BackgroundWorker *worker,
return success;
}
+bool
+RegisterDynamicBackgroundWorker(BackgroundWorker *worker,
+
BackgroundWorkerHandle **handle)
+{
+ /* public API, not a parallel worker */
+ return RegisterDynamicBackgroundWorkerInternal(worker, handle, false);
+}
+
/*
* Get the PID of a dynamically-registered background worker.
*
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 9b02111..18fa5b5 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2657,6 +2657,16 @@ static struct config_int ConfigureNamesInt[] =
},
{
+ {"max_parallel_workers", PGC_USERSET, RESOURCES_ASYNCHRONOUS,
+ gettext_noop("Sets the maximum number of parallel
processes for the cluster."),
+ NULL
+ },
+ &max_parallel_workers,
+ 2, 0, 1024,
+ NULL, NULL, NULL
+ },
+
+ {
{"autovacuum_work_mem", PGC_SIGHUP, RESOURCES_MEM,
gettext_noop("Sets the maximum memory to be used by
each autovacuum worker process."),
NULL,
diff --git a/src/backend/utils/misc/postgresql.conf.sample
b/src/backend/utils/misc/postgresql.conf.sample
index 8260e37..7f16050 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -168,6 +168,7 @@
#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching
#max_worker_processes = 8 # (change requires restart)
#max_parallel_workers_per_gather = 2 # taken from max_worker_processes
+#max_parallel_workers = 4 # total maximum number of worker_processes
#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate
#
(change requires restart)
#backend_flush_after = 0 # 0 disables, default is 0
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index f41f9e9..eca5c1e 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -55,6 +55,7 @@ extern PGDLLIMPORT double parallel_setup_cost;
extern PGDLLIMPORT int effective_cache_size;
extern Cost disable_cost;
extern int max_parallel_workers_per_gather;
+extern int max_parallel_workers;
extern bool enable_seqscan;
extern bool enable_indexscan;
extern bool enable_indexonlyscan;
diff --git a/src/include/postmaster/bgworker.h
b/src/include/postmaster/bgworker.h
index b6889a3..958bc57 100644
--- a/src/include/postmaster/bgworker.h
+++ b/src/include/postmaster/bgworker.h
@@ -107,6 +107,9 @@ extern void RegisterBackgroundWorker(BackgroundWorker
*worker);
/* Register a new bgworker from a regular backend */
extern bool RegisterDynamicBackgroundWorker(BackgroundWorker *worker,
BackgroundWorkerHandle **handle);
+extern bool RegisterDynamicBackgroundWorkerInternal(BackgroundWorker *worker,
+
BackgroundWorkerHandle **handle,
+ bool parallel);
/* Query the status of a bgworker */
extern BgwHandleStatus GetBackgroundWorkerPid(BackgroundWorkerHandle *handle,
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers