aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2015-10-16 11:58:27 -0400
committerRobert Haas <rhaas@postgresql.org>2015-10-16 11:58:27 -0400
commita53c06a13eb4669d08ce8a5199aee51f88dd453e (patch)
tree659ccd9502bbd1b0f1593a6882f9ee5d36b2b98a
parentbfc78d7196eb28cd4e3d6c24f7e607bacecf1129 (diff)
downloadpostgresql-a53c06a13eb4669d08ce8a5199aee51f88dd453e.tar.gz
postgresql-a53c06a13eb4669d08ce8a5199aee51f88dd453e.zip
Prohibit parallel query when the isolation level is serializable.
In order for this to be safe, the code which hands true serializability will need to taught that the SIRead locks taken by a parallel worker pertain to the same transaction as those taken by the parallel leader. Some further changes may be needed as well. Until the necessary adaptations are made, don't generate parallel plans in serializable mode, and if a previously-generated parallel plan is used after serializable mode has been activated, run it serially. This fixes a bug in commit 7aea8e4f2daa4b39ca9d1309a0c4aadb0f7ed81b.
-rw-r--r--src/backend/access/transam/parallel.c8
-rw-r--r--src/backend/optimizer/plan/planner.c10
2 files changed, 18 insertions, 0 deletions
diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index 9c7428f5d6c..17f9a5ae6e4 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 e1ee67cd602..536b55e4930 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);
/*