diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index 9c7428f5d6c6efdf4ca274001c1c384f4856c7dc..17f9a5ae6e433e0bb4349f403805ae29d19f71ed 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -135,6 +135,14 @@ CreateParallelContext(parallel_worker_main_type entrypoint, int nworkers) if (dynamic_shared_memory_type == DSM_IMPL_NONE) 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. + */ + if (IsolationIsSerializable()) + nworkers = 0; + /* We might be running in a short-lived memory context. */ oldcontext = MemoryContextSwitchTo(TopTransactionContext); diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index e1ee67cd60275a4fb3ed1ef17f09b4be17825c86..536b55e4930557fc08ae93f7fc130aa44873ad8f 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -20,6 +20,7 @@ #include "access/htup_details.h" #include "access/parallel.h" +#include "access/xact.h" #include "executor/executor.h" #include "executor/nodeAgg.h" #include "foreign/fdwapi.h" @@ -210,11 +211,20 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) * a parallel worker. We might eventually be able to relax this * restriction, but for now it seems best not to have parallel workers * trying to create their own parallel workers. + * + * We can't use parallelism in serializable mode because the predicate + * locking code is not parallel-aware. It's not catastrophic if someone + * tries to run a parallel plan in serializable mode; it just won't get + * any workers and will run serially. But it seems like a good heuristic + * to assume that the same serialization level will be in effect at plan + * time and execution time, so don't generate a parallel plan if we're + * in serializable mode. */ glob->parallelModeOK = (cursorOptions & CURSOR_OPT_PARALLEL_OK) != 0 && IsUnderPostmaster && dynamic_shared_memory_type != DSM_IMPL_NONE && parse->commandType == CMD_SELECT && !parse->hasModifyingCTE && parse->utilityStmt == NULL && !IsParallelWorker() && + !IsolationIsSerializable() && !contain_parallel_unsafe((Node *) parse); /*