Skip to content

Commit 0075d78

Browse files
committed
Allow "internal" subtransactions in parallel mode.
Allow use of BeginInternalSubTransaction() in parallel mode, so long as the subtransaction doesn't attempt to acquire an XID or increment the command counter. Given those restrictions, the other parallel processes don't need to know about the subtransaction at all, so this should be safe. The benefit is that it allows subtransactions intended for error recovery, such as pl/pgsql exception blocks, to be used in PARALLEL SAFE functions. Another reason for doing this is that the API of BeginInternalSubTransaction() doesn't allow reporting failure. pl/python for one, and perhaps other PLs, copes very poorly with an error longjmp out of BeginInternalSubTransaction(). The headline feature of this patch removes the only easily-triggerable failure case within that function. There remain some resource-exhaustion and similar cases, which we now deal with by promoting them to FATAL errors, so that callers need not try to clean up. (It is likely that such errors would leave us with corrupted transaction state inside xact.c, making recovery difficult if not impossible anyway.) Although this work started because of a report of a pl/python crash, we're not going to do anything about that in the back branches. Back-patching this particular fix is obviously not very wise. While we could contemplate some narrower band-aid, pl/python is already an untrusted language, so it seems okay to classify this as a "so don't do that" case. Patch by me, per report from Hao Zhang. Thanks to Robert Haas for review. Discussion: https://postgr.es/m/CALY6Dr-2yLVeVPhNMhuBnRgOZo1UjoTETgtKBx1B2gUi8yy+3g@mail.gmail.com
1 parent e2395cd commit 0075d78

File tree

7 files changed

+181
-88
lines changed

7 files changed

+181
-88
lines changed

doc/src/sgml/parallel.sgml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -545,10 +545,10 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
545545
</para>
546546

547547
<para>
548-
Functions and aggregates must be marked <literal>PARALLEL UNSAFE</literal> if
549-
they write to the database, access sequences, change the transaction state
550-
even temporarily (e.g., a PL/pgSQL function that establishes an
551-
<literal>EXCEPTION</literal> block to catch errors), or make persistent changes to
548+
Functions and aggregates must be marked <literal>PARALLEL UNSAFE</literal>
549+
if they write to the database, change the transaction state (other than by
550+
using a subtransaction for error recovery), access sequences, or make
551+
persistent changes to
552552
settings. Similarly, functions must be marked <literal>PARALLEL
553553
RESTRICTED</literal> if they access temporary tables, client connection state,
554554
cursors, prepared statements, or miscellaneous backend-local state that

doc/src/sgml/ref/create_function.sgml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -428,22 +428,24 @@ CREATE [ OR REPLACE ] FUNCTION
428428
<term><literal>PARALLEL</literal></term>
429429

430430
<listitem>
431-
<para><literal>PARALLEL UNSAFE</literal> indicates that the function
432-
can't be executed in parallel mode and the presence of such a
431+
<para>
432+
<literal>PARALLEL UNSAFE</literal> indicates that the function
433+
can't be executed in parallel mode; the presence of such a
433434
function in an SQL statement forces a serial execution plan. This is
434435
the default. <literal>PARALLEL RESTRICTED</literal> indicates that
435-
the function can be executed in parallel mode, but the execution is
436-
restricted to parallel group leader. <literal>PARALLEL SAFE</literal>
436+
the function can be executed in parallel mode, but only in the parallel
437+
group leader process. <literal>PARALLEL SAFE</literal>
437438
indicates that the function is safe to run in parallel mode without
438-
restriction.
439+
restriction, including in parallel worker processes.
439440
</para>
440441

441442
<para>
442443
Functions should be labeled parallel unsafe if they modify any database
443-
state, or if they make changes to the transaction such as using
444-
sub-transactions, or if they access sequences or attempt to make
445-
persistent changes to settings (e.g., <literal>setval</literal>). They should
446-
be labeled as parallel restricted if they access temporary tables,
444+
state, change the transaction state (other than by using a
445+
subtransaction for error recovery), access sequences (e.g., by
446+
calling <literal>currval</literal>) or make persistent changes to
447+
settings. They should
448+
be labeled parallel restricted if they access temporary tables,
447449
client connection state, cursors, prepared statements, or miscellaneous
448450
backend-local state which the system cannot synchronize in parallel mode
449451
(e.g., <literal>setseed</literal> cannot be executed other than by the group

src/backend/access/transam/README.parallel

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ Transaction Integration
137137
=======================
138138

139139
Regardless of what the TransactionState stack looks like in the parallel
140-
leader, each parallel worker ends up with a stack of depth 1. This stack
140+
leader, each parallel worker begins with a stack of depth 1. This stack
141141
entry is marked with the special transaction block state
142142
TBLOCK_PARALLEL_INPROGRESS so that it's not confused with an ordinary
143143
toplevel transaction. The XID of this TransactionState is set to the XID of
@@ -153,18 +153,18 @@ associated with the memory contexts or resource owners of intermediate
153153
subtransactions.
154154

155155
No meaningful change to the transaction state can be made while in parallel
156-
mode. No XIDs can be assigned, and no subtransactions can start or end,
156+
mode. No XIDs can be assigned, and no command counter increments can happen,
157157
because we have no way of communicating these state changes to cooperating
158158
backends, or of synchronizing them. It's clearly unworkable for the initiating
159159
backend to exit any transaction or subtransaction that was in progress when
160160
parallelism was started before all parallel workers have exited; and it's even
161161
more clearly crazy for a parallel worker to try to subcommit or subabort the
162162
current subtransaction and execute in some other transaction context than was
163-
present in the initiating backend. It might be practical to allow internal
164-
sub-transactions (e.g. to implement a PL/pgSQL EXCEPTION block) to be used in
165-
parallel mode, provided that they are XID-less, because other backends
166-
wouldn't really need to know about those transactions or do anything
167-
differently because of them. Right now, we don't even allow that.
163+
present in the initiating backend. However, we allow internal subtransactions
164+
(e.g. those used to implement a PL/pgSQL EXCEPTION block) to be used in
165+
parallel mode, provided that they remain XID-less, because other backends
166+
don't really need to know about those transactions or do anything differently
167+
because of them.
168168

169169
At the end of a parallel operation, which can happen either because it
170170
completed successfully or because it was interrupted by an error, parallel

src/backend/access/transam/parallel.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,10 +1226,8 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
12261226
/*
12271227
* End-of-subtransaction cleanup for parallel contexts.
12281228
*
1229-
* Currently, it's forbidden to enter or leave a subtransaction while
1230-
* parallel mode is in effect, so we could just blow away everything. But
1231-
* we may want to relax that restriction in the future, so this code
1232-
* contemplates that there may be multiple subtransaction IDs in pcxt_list.
1229+
* Here we remove only parallel contexts initiated within the current
1230+
* subtransaction.
12331231
*/
12341232
void
12351233
AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
@@ -1249,6 +1247,8 @@ AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
12491247

12501248
/*
12511249
* End-of-transaction cleanup for parallel contexts.
1250+
*
1251+
* We nuke all remaining parallel contexts.
12521252
*/
12531253
void
12541254
AtEOXact_Parallel(bool isCommit)

0 commit comments

Comments
 (0)