From 0075d78947e3800c5a807f48fd901f16db91101b Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 28 Mar 2024 12:43:10 -0400 Subject: 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 --- src/backend/access/transam/README.parallel | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/backend/access/transam/README.parallel') diff --git a/src/backend/access/transam/README.parallel b/src/backend/access/transam/README.parallel index e486bffc475..9df3da91b0c 100644 --- a/src/backend/access/transam/README.parallel +++ b/src/backend/access/transam/README.parallel @@ -137,7 +137,7 @@ Transaction Integration ======================= Regardless of what the TransactionState stack looks like in the parallel -leader, each parallel worker ends up with a stack of depth 1. This stack +leader, each parallel worker begins with a stack of depth 1. This stack entry is marked with the special transaction block state TBLOCK_PARALLEL_INPROGRESS so that it's not confused with an ordinary 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 subtransactions. No meaningful change to the transaction state can be made while in parallel -mode. No XIDs can be assigned, and no subtransactions can start or end, +mode. No XIDs can be assigned, and no command counter increments can happen, because we have no way of communicating these state changes to cooperating backends, or of synchronizing them. It's clearly unworkable for the initiating backend to exit any transaction or subtransaction that was in progress when parallelism was started before all parallel workers have exited; and it's even more clearly crazy for a parallel worker to try to subcommit or subabort the current subtransaction and execute in some other transaction context than was -present in the initiating backend. It might be practical to allow internal -sub-transactions (e.g. to implement a PL/pgSQL EXCEPTION block) to be used in -parallel mode, provided that they are XID-less, because other backends -wouldn't really need to know about those transactions or do anything -differently because of them. Right now, we don't even allow that. +present in the initiating backend. However, we allow internal subtransactions +(e.g. those used to implement a PL/pgSQL EXCEPTION block) to be used in +parallel mode, provided that they remain XID-less, because other backends +don't really need to know about those transactions or do anything differently +because of them. At the end of a parallel operation, which can happen either because it completed successfully or because it was interrupted by an error, parallel -- cgit v1.2.3