mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Determine whether it's safe to attempt a parallel plan for a query.
Commit 924bcf4f16
introduced a framework
for parallel computation in PostgreSQL that makes most but not all
built-in functions safe to execute in parallel mode. In order to have
parallel query, we'll need to be able to determine whether that query
contains functions (either built-in or user-defined) that cannot be
safely executed in parallel mode. This requires those functions to be
labeled, so this patch introduces an infrastructure for that. Some
functions currently labeled as safe may need to be revised depending on
how pending issues related to heavyweight locking under paralllelism
are resolved.
Parallel plans can't be used except for the case where the query will
run to completion. If portal execution were suspended, the parallel
mode restrictions would need to remain in effect during that time, but
that might make other queries fail. Therefore, this patch introduces
a framework that enables consideration of parallel plans only when it
is known that the plan will be run to completion. This probably needs
some refinement; for example, at bind time, we do not know whether a
query run via the extended protocol will be execution to completion or
run with a limited fetch count. Having the client indicate its
intentions at bind time would constitute a wire protocol break. Some
contexts in which parallel mode would be safe are not adjusted by this
patch; the default is not to try parallel plans except from call sites
that have been updated to say that such plans are OK.
This commit doesn't introduce any parallel paths or plans; it just
provides a way to determine whether they could potentially be used.
I'm committing it on the theory that the remaining parallel sequential
scan patches will also get committed to this release, hopefully in the
not-too-distant future.
Robert Haas and Amit Kapila. Reviewed (in earlier versions) by Noah
Misch.
This commit is contained in:
@ -4994,6 +4994,23 @@
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>proparallel</structfield></entry>
|
||||
<entry><type>char</type></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
<structfield>proparallel</structfield> tells whether the function
|
||||
can be safely run in parallel mode.
|
||||
It is <literal>s</literal> for functions which are safe to run in
|
||||
parallel mode without restriction.
|
||||
It is <literal>r</literal> for functions which can be run in parallel
|
||||
mode, but their execution is restricted to the parallel group leader;
|
||||
parallel worker processes cannot invoke these functions.
|
||||
It is <literal>u</literal> for functions which are unsafe in parallel
|
||||
mode; the presence of such a function forces a serial execution plan.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>pronargs</structfield></entry>
|
||||
<entry><type>int2</type></entry>
|
||||
|
@ -35,6 +35,7 @@ ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="paramet
|
||||
CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
|
||||
IMMUTABLE | STABLE | VOLATILE | [ NOT ] LEAKPROOF
|
||||
[ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
|
||||
PARALLEL { UNSAFE | RESTRICTED | SAFE }
|
||||
COST <replaceable class="parameter">execution_cost</replaceable>
|
||||
ROWS <replaceable class="parameter">result_rows</replaceable>
|
||||
SET <replaceable class="parameter">configuration_parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> | DEFAULT }
|
||||
@ -191,6 +192,17 @@ ALTER FUNCTION <replaceable>name</replaceable> ( [ [ <replaceable class="paramet
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>PARALLEL</literal></term>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Change whether the function is deemed safe for parallelism.
|
||||
See <xref linkend="sql-createfunction"> for details.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>LEAKPROOF</literal></term>
|
||||
<listitem>
|
||||
|
@ -30,6 +30,7 @@ CREATE [ OR REPLACE ] FUNCTION
|
||||
| IMMUTABLE | STABLE | VOLATILE | [ NOT ] LEAKPROOF
|
||||
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
|
||||
| [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
|
||||
| PARALLEL { UNSAFE | RESTRICTED | SAFE }
|
||||
| COST <replaceable class="parameter">execution_cost</replaceable>
|
||||
| ROWS <replaceable class="parameter">result_rows</replaceable>
|
||||
| SET <replaceable class="parameter">configuration_parameter</replaceable> { TO <replaceable class="parameter">value</replaceable> | = <replaceable class="parameter">value</replaceable> | FROM CURRENT }
|
||||
@ -411,6 +412,43 @@ CREATE [ OR REPLACE ] FUNCTION
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>PARALLEL</literal></term>
|
||||
|
||||
<listitem>
|
||||
<para><literal>PARALLEL UNSAFE</literal> indicates that the function
|
||||
can't be executed in parallel mode and the presence of such a
|
||||
function in an SQL statement forces a serial execution plan. This is
|
||||
the default. <literal>PARALLEL RESTRICTED</literal> indicates that
|
||||
the function can be executed in parallel mode, but the execution is
|
||||
restricted to parallel group leader. <literal>PARALLEL SAFE</literal>
|
||||
indicates that the function is safe to run in parallel mode without
|
||||
restriction.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Functions should be labeled parallel unsafe if they modify any database
|
||||
state, or if they make changes to the transaction such as using
|
||||
sub-transactions, or if they access sequences or attempt to make
|
||||
persistent changes to settings (e.g. <literal>setval</>). They should
|
||||
be labeled as parallel restricted if they access temporary tables,
|
||||
client connection state, cursors, prepared statements, or miscellaneous
|
||||
backend-local state which the system cannot synchronize in parallel mode
|
||||
(e.g. <literal>setseed</> cannot be executed other than by the group
|
||||
leader because a change made by another process would not be reflected
|
||||
in the leader). In general, if a function is labeled as being safe when
|
||||
it is restricted or unsafe, or if it is labeled as being restricted when
|
||||
it is in fact unsafe, it may throw errors or produce wrong answers
|
||||
when used in a parallel query. C-language functions could in theory
|
||||
exhibit totally undefined behavior if mislabeled, since there is no way
|
||||
for the system to protect itself against arbitrary C code, but in most
|
||||
likely cases the result will be no worse than for any other function.
|
||||
If in doubt, functions should be labeled as <literal>UNSAFE</>, which is
|
||||
the default.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable class="parameter">execution_cost</replaceable></term>
|
||||
|
||||
|
Reference in New Issue
Block a user