diff options
author | Thomas Munro <tmunro@postgresql.org> | 2019-03-15 16:23:46 +1300 |
---|---|---|
committer | Thomas Munro <tmunro@postgresql.org> | 2019-03-15 17:47:04 +1300 |
commit | bb16aba50c9492490a0b57e600a932798f45cd4f (patch) | |
tree | 36991984cfb9e141b42c4caf5f1056974526f617 /src/backend/access/transam/parallel.c | |
parent | 13e8643bfc29d3c1455c0946281cdfc24758ffb6 (diff) | |
download | postgresql-bb16aba50c9492490a0b57e600a932798f45cd4f.tar.gz postgresql-bb16aba50c9492490a0b57e600a932798f45cd4f.zip |
Enable parallel query with SERIALIZABLE isolation.
Previously, the SERIALIZABLE isolation level prevented parallel query
from being used. Allow the two features to be used together by
sharing the leader's SERIALIZABLEXACT with parallel workers.
An extra per-SERIALIZABLEXACT LWLock is introduced to make it safe to
share, and new logic is introduced to coordinate the early release
of the SERIALIZABLEXACT required for the SXACT_FLAG_RO_SAFE
optimization, as follows:
The first backend to observe the SXACT_FLAG_RO_SAFE flag (set by
some other transaction) will 'partially release' the SERIALIZABLEXACT,
meaning that the conflicts and locks it holds are released, but the
SERIALIZABLEXACT itself will remain active because other backends
might still have a pointer to it.
Whenever any backend notices the SXACT_FLAG_RO_SAFE flag, it clears
its own MySerializableXact variable and frees local resources so that
it can skip SSI checks for the rest of the transaction. In the
special case of the leader process, it transfers the SERIALIZABLEXACT
to a new variable SavedSerializableXact, so that it can be completely
released at the end of the transaction after all workers have exited.
Remove the serializable_okay flag added to CreateParallelContext() by
commit 9da0cc35, because it's now redundant.
Author: Thomas Munro
Reviewed-by: Haribabu Kommi, Robert Haas, Masahiko Sawada, Kevin Grittner
Discussion: https://postgr.es/m/CAEepm=0gXGYhtrVDWOTHS8SQQy_=S9xo+8oCxGLWZAOoeJ=yzQ@mail.gmail.com
Diffstat (limited to 'src/backend/access/transam/parallel.c')
-rw-r--r-- | src/backend/access/transam/parallel.c | 18 |
1 files changed, 7 insertions, 11 deletions
diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index ce2b61631db..55d129a64f7 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -31,6 +31,7 @@ #include "optimizer/optimizer.h" #include "pgstat.h" #include "storage/ipc.h" +#include "storage/predicate.h" #include "storage/sinval.h" #include "storage/spin.h" #include "tcop/tcopprot.h" @@ -91,6 +92,7 @@ typedef struct FixedParallelState BackendId parallel_master_backend_id; TimestampTz xact_ts; TimestampTz stmt_ts; + SerializableXactHandle serializable_xact_handle; /* Mutex protects remaining fields. */ slock_t mutex; @@ -155,7 +157,7 @@ static void ParallelWorkerShutdown(int code, Datum arg); */ ParallelContext * CreateParallelContext(const char *library_name, const char *function_name, - int nworkers, bool serializable_okay) + int nworkers) { MemoryContext oldcontext; ParallelContext *pcxt; @@ -166,16 +168,6 @@ CreateParallelContext(const char *library_name, const char *function_name, /* Number of workers should be non-negative. */ Assert(nworkers >= 0); - /* - * If we are running under serializable isolation, we can't use parallel - * workers, at least not until somebody enhances that mechanism to be - * parallel-aware. Utility statement callers may ask us to ignore this - * restriction because they're always able to safely ignore the fact that - * SIREAD locks do not work with parallelism. - */ - if (IsolationIsSerializable() && !serializable_okay) - nworkers = 0; - /* We might be running in a short-lived memory context. */ oldcontext = MemoryContextSwitchTo(TopTransactionContext); @@ -327,6 +319,7 @@ InitializeParallelDSM(ParallelContext *pcxt) fps->parallel_master_backend_id = MyBackendId; fps->xact_ts = GetCurrentTransactionStartTimestamp(); fps->stmt_ts = GetCurrentStatementStartTimestamp(); + fps->serializable_xact_handle = ShareSerializableXact(); SpinLockInit(&fps->mutex); fps->last_xlog_end = 0; shm_toc_insert(pcxt->toc, PARALLEL_KEY_FIXED, fps); @@ -1422,6 +1415,9 @@ ParallelWorkerMain(Datum main_arg) false); RestoreEnumBlacklist(enumblacklistspace); + /* Attach to the leader's serializable transaction, if SERIALIZABLE. */ + AttachSerializableXact(fps->serializable_xact_handle); + /* * We've initialized all of our state now; nothing should change * hereafter. |