summaryrefslogtreecommitdiff
path: root/src/backend/executor/execParallel.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2017-08-29 13:22:49 -0400
committerRobert Haas <rhaas@postgresql.org>2017-08-29 13:26:33 -0400
commitbf11e7ee2e3607bb67d25aec73aa53b2d7e9961b (patch)
tree89c3d26f157949896e1a69c1ea4f4ae5b64833ee /src/backend/executor/execParallel.c
parent3452dc5240da43e833118484e1e9b4894d04431c (diff)
downloadpostgresql-bf11e7ee2e3607bb67d25aec73aa53b2d7e9961b.tar.gz
Propagate sort instrumentation from workers back to leader.
Up until now, when parallel query was used, no details about the sort method or space used by the workers were available; details were shown only for any sorting done by the leader. Fix that. Commit 1177ab1dabf72bafee8f19d904cee3a299f25892 forced the test case added by commit 1f6d515a67ec98194c23a5db25660856c9aab944 to run without parallelism; now that we have this infrastructure, allow that again, with a little tweaking to make it pass with and without force_parallel_mode. Robert Haas and Tom Lane Discussion: http://postgr.es/m/CA+Tgmoa2VBZW6S8AAXfhpHczb=Rf6RqQ2br+zJvEgwJ0uoD_tQ@mail.gmail.com
Diffstat (limited to 'src/backend/executor/execParallel.c')
-rw-r--r--src/backend/executor/execParallel.c155
1 files changed, 89 insertions, 66 deletions
diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c
index ad9eba63dd..01316ff5d9 100644
--- a/src/backend/executor/execParallel.c
+++ b/src/backend/executor/execParallel.c
@@ -28,9 +28,10 @@
#include "executor/nodeBitmapHeapscan.h"
#include "executor/nodeCustom.h"
#include "executor/nodeForeignscan.h"
-#include "executor/nodeSeqscan.h"
#include "executor/nodeIndexscan.h"
#include "executor/nodeIndexonlyscan.h"
+#include "executor/nodeSeqscan.h"
+#include "executor/nodeSort.h"
#include "executor/tqueue.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/planmain.h"
@@ -202,10 +203,10 @@ ExecSerializePlan(Plan *plan, EState *estate)
}
/*
- * Ordinary plan nodes won't do anything here, but parallel-aware plan nodes
- * may need some state which is shared across all parallel workers. Before
- * we size the DSM, give them a chance to call shm_toc_estimate_chunk or
- * shm_toc_estimate_keys on &pcxt->estimator.
+ * Parallel-aware plan nodes (and occasionally others) may need some state
+ * which is shared across all parallel workers. Before we size the DSM, give
+ * them a chance to call shm_toc_estimate_chunk or shm_toc_estimate_keys on
+ * &pcxt->estimator.
*
* While we're at it, count the number of PlanState nodes in the tree, so
* we know how many SharedPlanStateInstrumentation structures we need.
@@ -219,38 +220,43 @@ ExecParallelEstimate(PlanState *planstate, ExecParallelEstimateContext *e)
/* Count this node. */
e->nnodes++;
- /* Call estimators for parallel-aware nodes. */
- if (planstate->plan->parallel_aware)
+ switch (nodeTag(planstate))
{
- switch (nodeTag(planstate))
- {
- case T_SeqScanState:
+ case T_SeqScanState:
+ if (planstate->plan->parallel_aware)
ExecSeqScanEstimate((SeqScanState *) planstate,
e->pcxt);
- break;
- case T_IndexScanState:
+ break;
+ case T_IndexScanState:
+ if (planstate->plan->parallel_aware)
ExecIndexScanEstimate((IndexScanState *) planstate,
e->pcxt);
- break;
- case T_IndexOnlyScanState:
+ break;
+ case T_IndexOnlyScanState:
+ if (planstate->plan->parallel_aware)
ExecIndexOnlyScanEstimate((IndexOnlyScanState *) planstate,
e->pcxt);
- break;
- case T_ForeignScanState:
+ break;
+ case T_ForeignScanState:
+ if (planstate->plan->parallel_aware)
ExecForeignScanEstimate((ForeignScanState *) planstate,
e->pcxt);
- break;
- case T_CustomScanState:
+ break;
+ case T_CustomScanState:
+ if (planstate->plan->parallel_aware)
ExecCustomScanEstimate((CustomScanState *) planstate,
e->pcxt);
- break;
- case T_BitmapHeapScanState:
+ break;
+ case T_BitmapHeapScanState:
+ if (planstate->plan->parallel_aware)
ExecBitmapHeapEstimate((BitmapHeapScanState *) planstate,
e->pcxt);
- break;
- default:
- break;
- }
+ break;
+ case T_SortState:
+ /* even when not parallel-aware */
+ ExecSortEstimate((SortState *) planstate, e->pcxt);
+ default:
+ break;
}
return planstate_tree_walker(planstate, ExecParallelEstimate, e);
@@ -276,46 +282,51 @@ ExecParallelInitializeDSM(PlanState *planstate,
d->nnodes++;
/*
- * Call initializers for parallel-aware plan nodes.
+ * Call initializers for DSM-using plan nodes.
*
- * Ordinary plan nodes won't do anything here, but parallel-aware plan
- * nodes may need to initialize shared state in the DSM before parallel
- * workers are available. They can allocate the space they previously
+ * Most plan nodes won't do anything here, but plan nodes that allocated
+ * DSM may need to initialize shared state in the DSM before parallel
+ * workers are launched. They can allocate the space they previously
* estimated using shm_toc_allocate, and add the keys they previously
* estimated using shm_toc_insert, in each case targeting pcxt->toc.
*/
- if (planstate->plan->parallel_aware)
+ switch (nodeTag(planstate))
{
- switch (nodeTag(planstate))
- {
- case T_SeqScanState:
+ case T_SeqScanState:
+ if (planstate->plan->parallel_aware)
ExecSeqScanInitializeDSM((SeqScanState *) planstate,
d->pcxt);
- break;
- case T_IndexScanState:
+ break;
+ case T_IndexScanState:
+ if (planstate->plan->parallel_aware)
ExecIndexScanInitializeDSM((IndexScanState *) planstate,
d->pcxt);
- break;
- case T_IndexOnlyScanState:
+ break;
+ case T_IndexOnlyScanState:
+ if (planstate->plan->parallel_aware)
ExecIndexOnlyScanInitializeDSM((IndexOnlyScanState *) planstate,
d->pcxt);
- break;
- case T_ForeignScanState:
+ break;
+ case T_ForeignScanState:
+ if (planstate->plan->parallel_aware)
ExecForeignScanInitializeDSM((ForeignScanState *) planstate,
d->pcxt);
- break;
- case T_CustomScanState:
+ break;
+ case T_CustomScanState:
+ if (planstate->plan->parallel_aware)
ExecCustomScanInitializeDSM((CustomScanState *) planstate,
d->pcxt);
- break;
- case T_BitmapHeapScanState:
+ break;
+ case T_BitmapHeapScanState:
+ if (planstate->plan->parallel_aware)
ExecBitmapHeapInitializeDSM((BitmapHeapScanState *) planstate,
d->pcxt);
- break;
-
- default:
- break;
- }
+ break;
+ case T_SortState:
+ /* even when not parallel-aware */
+ ExecSortInitializeDSM((SortState *) planstate, d->pcxt);
+ default:
+ break;
}
return planstate_tree_walker(planstate, ExecParallelInitializeDSM, d);
@@ -642,6 +653,13 @@ ExecParallelRetrieveInstrumentation(PlanState *planstate,
planstate->worker_instrument->num_workers = instrumentation->num_workers;
memcpy(&planstate->worker_instrument->instrument, instrument, ibytes);
+ /*
+ * Perform any node-type-specific work that needs to be done. Currently,
+ * only Sort nodes need to do anything here.
+ */
+ if (IsA(planstate, SortState))
+ ExecSortRetrieveInstrumentation((SortState *) planstate);
+
return planstate_tree_walker(planstate, ExecParallelRetrieveInstrumentation,
instrumentation);
}
@@ -801,35 +819,40 @@ ExecParallelInitializeWorker(PlanState *planstate, shm_toc *toc)
if (planstate == NULL)
return false;
- /* Call initializers for parallel-aware plan nodes. */
- if (planstate->plan->parallel_aware)
+ switch (nodeTag(planstate))
{
- switch (nodeTag(planstate))
- {
- case T_SeqScanState:
+ case T_SeqScanState:
+ if (planstate->plan->parallel_aware)
ExecSeqScanInitializeWorker((SeqScanState *) planstate, toc);
- break;
- case T_IndexScanState:
+ break;
+ case T_IndexScanState:
+ if (planstate->plan->parallel_aware)
ExecIndexScanInitializeWorker((IndexScanState *) planstate, toc);
- break;
- case T_IndexOnlyScanState:
+ break;
+ case T_IndexOnlyScanState:
+ if (planstate->plan->parallel_aware)
ExecIndexOnlyScanInitializeWorker((IndexOnlyScanState *) planstate, toc);
- break;
- case T_ForeignScanState:
+ break;
+ case T_ForeignScanState:
+ if (planstate->plan->parallel_aware)
ExecForeignScanInitializeWorker((ForeignScanState *) planstate,
toc);
- break;
- case T_CustomScanState:
+ break;
+ case T_CustomScanState:
+ if (planstate->plan->parallel_aware)
ExecCustomScanInitializeWorker((CustomScanState *) planstate,
toc);
- break;
- case T_BitmapHeapScanState:
+ break;
+ case T_BitmapHeapScanState:
+ if (planstate->plan->parallel_aware)
ExecBitmapHeapInitializeWorker(
(BitmapHeapScanState *) planstate, toc);
- break;
- default:
- break;
- }
+ break;
+ case T_SortState:
+ /* even when not parallel-aware */
+ ExecSortInitializeWorker((SortState *) planstate, toc);
+ default:
+ break;
}
return planstate_tree_walker(planstate, ExecParallelInitializeWorker, toc);