switch (nodeTag(planstate))
{ case T_SeqScanState: if (planstate->plan->parallel_aware)
ExecSeqScanEstimate((SeqScanState *) planstate,
e->pcxt); break; case T_IndexScanState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecIndexScanEstimate((IndexScanState *) planstate,
e->pcxt); break; case T_IndexOnlyScanState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecIndexOnlyScanEstimate((IndexOnlyScanState *) planstate,
e->pcxt); break; case T_BitmapIndexScanState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecBitmapIndexScanEstimate((BitmapIndexScanState *) planstate,
e->pcxt); break; case T_ForeignScanState: if (planstate->plan->parallel_aware)
ExecForeignScanEstimate((ForeignScanState *) planstate,
e->pcxt); break; case T_AppendState: if (planstate->plan->parallel_aware)
ExecAppendEstimate((AppendState *) planstate,
e->pcxt); break; case T_CustomScanState: if (planstate->plan->parallel_aware)
ExecCustomScanEstimate((CustomScanState *) planstate,
e->pcxt); break; case T_BitmapHeapScanState: if (planstate->plan->parallel_aware)
ExecBitmapHeapEstimate((BitmapHeapScanState *) planstate,
e->pcxt); break; case T_HashJoinState: if (planstate->plan->parallel_aware)
ExecHashJoinEstimate((HashJoinState *) planstate,
e->pcxt); break; case T_HashState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecHashEstimate((HashState *) planstate, e->pcxt); break; case T_SortState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecSortEstimate((SortState *) planstate, e->pcxt); break; case T_IncrementalSortState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecIncrementalSortEstimate((IncrementalSortState *) planstate, e->pcxt); break; case T_AggState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecAggEstimate((AggState *) planstate, e->pcxt); break; case T_MemoizeState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecMemoizeEstimate((MemoizeState *) planstate, e->pcxt); break; default: break;
}
/* Allocate enough space for the current parameter values. */
size = EstimateParamExecSpace(estate, params);
handle = dsa_allocate(area, size);
start_address = dsa_get_address(area, handle);
/* First write the number of parameters as a 4-byte integer. */
nparams = bms_num_members(params);
memcpy(start_address, &nparams, sizeof(int));
start_address += sizeof(int);
/* Write details for each parameter in turn. */
paramid = -1; while ((paramid = bms_next_member(params, paramid)) >= 0)
{
Oid typeOid;
int16 typLen; bool typByVal;
/* If instrumentation is enabled, initialize slot for this node. */ if (d->instrumentation != NULL)
d->instrumentation->plan_node_id[d->nnodes] =
planstate->plan->plan_node_id;
/* Count this node. */
d->nnodes++;
/* *CallinitializersforDSM-usingplannodes. * *Mostplannodeswon'tdoanythinghere,butplannodesthatallocated *DSMmayneedtoinitializesharedstateintheDSMbeforeparallel *workersarelaunched.Theycanallocatethespacetheypreviously *estimatedusingshm_toc_allocate,andaddthekeystheypreviously *estimatedusingshm_toc_insert,ineachcasetargetingpcxt->toc.
*/ switch (nodeTag(planstate))
{ case T_SeqScanState: if (planstate->plan->parallel_aware)
ExecSeqScanInitializeDSM((SeqScanState *) planstate,
d->pcxt); break; case T_IndexScanState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecIndexScanInitializeDSM((IndexScanState *) planstate, d->pcxt); break; case T_IndexOnlyScanState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecIndexOnlyScanInitializeDSM((IndexOnlyScanState *) planstate,
d->pcxt); break; case T_BitmapIndexScanState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecBitmapIndexScanInitializeDSM((BitmapIndexScanState *) planstate, d->pcxt); break; case T_ForeignScanState: if (planstate->plan->parallel_aware)
ExecForeignScanInitializeDSM((ForeignScanState *) planstate,
d->pcxt); break; case T_AppendState: if (planstate->plan->parallel_aware)
ExecAppendInitializeDSM((AppendState *) planstate,
d->pcxt); break; case T_CustomScanState: if (planstate->plan->parallel_aware)
ExecCustomScanInitializeDSM((CustomScanState *) planstate,
d->pcxt); break; case T_BitmapHeapScanState: if (planstate->plan->parallel_aware)
ExecBitmapHeapInitializeDSM((BitmapHeapScanState *) planstate,
d->pcxt); break; case T_HashJoinState: if (planstate->plan->parallel_aware)
ExecHashJoinInitializeDSM((HashJoinState *) planstate,
d->pcxt); break; case T_HashState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecHashInitializeDSM((HashState *) planstate, d->pcxt); break; case T_SortState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecSortInitializeDSM((SortState *) planstate, d->pcxt); break; case T_IncrementalSortState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecIncrementalSortInitializeDSM((IncrementalSortState *) planstate, d->pcxt); break; case T_AggState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecAggInitializeDSM((AggState *) planstate, d->pcxt); break; case T_MemoizeState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecMemoizeInitializeDSM((MemoizeState *) planstate, d->pcxt); break; default: break;
}
/* Allocate space for each worker's BufferUsage; no need to initialize. */
bufusage_space = shm_toc_allocate(pcxt->toc,
mul_size(sizeof(BufferUsage), pcxt->nworkers));
shm_toc_insert(pcxt->toc, PARALLEL_KEY_BUFFER_USAGE, bufusage_space);
pei->buffer_usage = bufusage_space;
/* Same for WalUsage. */
walusage_space = shm_toc_allocate(pcxt->toc,
mul_size(sizeof(WalUsage), pcxt->nworkers));
shm_toc_insert(pcxt->toc, PARALLEL_KEY_WAL_USAGE, walusage_space);
pei->wal_usage = walusage_space;
/* Set up the tuple queues that the workers will write into. */
pei->tqueue = ExecParallelSetupTupleQueues(pcxt, false);
/* We don't need the TupleQueueReaders yet, though. */
pei->reader = NULL;
/* *Ifinstrumentationoptionsweresupplied,allocatespaceforthedata. *Itonlygetspartiallyinitializedhere;theresthappensduring *ExecParallelInitializeDSM.
*/ if (estate->es_instrument)
{
Instrumentation *instrument; int i;
/* Free any serialized parameters from the last round. */ if (DsaPointerIsValid(fpes->param_exec))
{
dsa_free(pei->area, fpes->param_exec);
fpes->param_exec = InvalidDsaPointer;
}
/* Serialize current parameter values if required. */ if (!bms_is_empty(sendParams))
{
pei->param_exec = SerializeParamExecParams(estate, sendParams,
pei->area);
fpes->param_exec = pei->param_exec;
}
/* Traverse plan tree and let each child node reset associated state. */
estate->es_query_dsa = pei->area;
ExecParallelReInitializeDSM(planstate, pei->pcxt);
estate->es_query_dsa = NULL;
}
/* *CallreinitializersforDSM-usingplannodes.
*/ switch (nodeTag(planstate))
{ case T_SeqScanState: if (planstate->plan->parallel_aware)
ExecSeqScanReInitializeDSM((SeqScanState *) planstate,
pcxt); break; case T_IndexScanState: if (planstate->plan->parallel_aware)
ExecIndexScanReInitializeDSM((IndexScanState *) planstate,
pcxt); break; case T_IndexOnlyScanState: if (planstate->plan->parallel_aware)
ExecIndexOnlyScanReInitializeDSM((IndexOnlyScanState *) planstate,
pcxt); break; case T_ForeignScanState: if (planstate->plan->parallel_aware)
ExecForeignScanReInitializeDSM((ForeignScanState *) planstate,
pcxt); break; case T_AppendState: if (planstate->plan->parallel_aware)
ExecAppendReInitializeDSM((AppendState *) planstate, pcxt); break; case T_CustomScanState: if (planstate->plan->parallel_aware)
ExecCustomScanReInitializeDSM((CustomScanState *) planstate,
pcxt); break; case T_BitmapHeapScanState: if (planstate->plan->parallel_aware)
ExecBitmapHeapReInitializeDSM((BitmapHeapScanState *) planstate,
pcxt); break; case T_HashJoinState: if (planstate->plan->parallel_aware)
ExecHashJoinReInitializeDSM((HashJoinState *) planstate,
pcxt); break; case T_BitmapIndexScanState: case T_HashState: case T_SortState: case T_IncrementalSortState: case T_MemoizeState: /* these nodes have DSM state, but no reinitialization is required */ break;
/* *Copyinstrumentationinformationaboutthisnodeanditsdescendantsfrom *dynamicsharedmemory.
*/ staticbool
ExecParallelRetrieveInstrumentation(PlanState *planstate,
SharedExecutorInstrumentation *instrumentation)
{
Instrumentation *instrument; int i; int n; int ibytes; int plan_node_id = planstate->plan->plan_node_id;
MemoryContext oldcontext;
/* Find the instrumentation for this node. */ for (i = 0; i < instrumentation->num_plan_nodes; ++i) if (instrumentation->plan_node_id[i] == plan_node_id) break; if (i >= instrumentation->num_plan_nodes)
elog(ERROR, "plan node %d not found", plan_node_id);
/* Accumulate the statistics from all workers. */
instrument = GetInstrumentationArray(instrumentation);
instrument += i * instrumentation->num_workers; for (n = 0; n < instrumentation->num_workers; ++n)
InstrAggNode(planstate->instrument, &instrument[n]);
/* *Finishparallelexecution.Wewaitforparallelworkerstofinish,and *accumulatetheirbuffer/WALusage.
*/ void
ExecParallelFinish(ParallelExecutorInfo *pei)
{ int nworkers = pei->pcxt->nworkers_launched; int i;
/* Make this be a no-op if called twice in a row. */ if (pei->finished) return;
/* *DetachfromtuplequeuesASAP,sothatanystill-activeworkerswill *noticethatnofurtherresultsarewanted.
*/ if (pei->tqueue != NULL)
{ for (i = 0; i < nworkers; i++)
shm_mq_detach(pei->tqueue[i]);
pfree(pei->tqueue);
pei->tqueue = NULL;
}
/* *Whilewe'rewaitingfortheworkerstofinish,let'sgetridofthe *tuplequeuereaders.(Anyotherlocalcleanupcouldbedoneheretoo.)
*/ if (pei->reader != NULL)
{ for (i = 0; i < nworkers; i++)
DestroyTupleQueueReader(pei->reader[i]);
pfree(pei->reader);
pei->reader = NULL;
}
/* Now wait for the workers to finish. */
WaitForParallelWorkersToFinish(pei->pcxt);
/* *Next,accumulatebuffer/WALusage.(Thismustwaitfortheworkersto *finish,orwemightgetincompletedata.)
*/ for (i = 0; i < nworkers; i++)
InstrAccumParallelQuery(&pei->buffer_usage[i], &pei->wal_usage[i]);
pei->finished = true;
}
/* *Accumulateinstrumentation,andthencleanupwhateverParallelExecutorInfo *resourcesstillexistafterExecParallelFinish.Weseparatethese *routinesbecausesomeonemightwanttoexaminethecontentsoftheDSM *afterExecParallelFinishandbeforecallingthisroutine.
*/ void
ExecParallelCleanup(ParallelExecutorInfo *pei)
{ /* Accumulate instrumentation, if any. */ if (pei->instrumentation)
ExecParallelRetrieveInstrumentation(pei->planstate,
pei->instrumentation);
/* Accumulate JIT instrumentation, if any. */ if (pei->jit_instrumentation)
ExecParallelRetrieveJitInstrumentation(pei->planstate,
pei->jit_instrumentation);
/* Free any serialized parameters. */ if (DsaPointerIsValid(pei->param_exec))
{
dsa_free(pei->area, pei->param_exec);
pei->param_exec = InvalidDsaPointer;
} if (pei->area != NULL)
{
dsa_detach(pei->area);
pei->area = NULL;
} if (pei->pcxt != NULL)
{
DestroyParallelContext(pei->pcxt);
pei->pcxt = NULL;
}
pfree(pei);
}
/* Create a QueryDesc for the query. */ return CreateQueryDesc(pstmt,
queryString,
GetActiveSnapshot(), InvalidSnapshot,
receiver, paramLI, NULL, instrument_options);
}
/* *Copyinstrumentationinformationfromthisnodeanditsdescendantsinto *dynamicsharedmemory,sothattheparallelleadercanretrieveit.
*/ staticbool
ExecParallelReportInstrumentation(PlanState *planstate,
SharedExecutorInstrumentation *instrumentation)
{ int i; int plan_node_id = planstate->plan->plan_node_id;
Instrumentation *instrument;
InstrEndLoop(planstate->instrument);
/* *Ifweshuffledtheplan_node_idvaluesinps_instrumentintosorted *order,wecouldusebinarysearchhere.Thismightmattersomedayif *we'repushingdownsufficientlylargeplantrees.Fornow,doitthe *slow,dumbway.
*/ for (i = 0; i < instrumentation->num_plan_nodes; ++i) if (instrumentation->plan_node_id[i] == plan_node_id) break; if (i >= instrumentation->num_plan_nodes)
elog(ERROR, "plan node %d not found", plan_node_id);
switch (nodeTag(planstate))
{ case T_SeqScanState: if (planstate->plan->parallel_aware)
ExecSeqScanInitializeWorker((SeqScanState *) planstate, pwcxt); break; case T_IndexScanState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecIndexScanInitializeWorker((IndexScanState *) planstate, pwcxt); break; case T_IndexOnlyScanState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecIndexOnlyScanInitializeWorker((IndexOnlyScanState *) planstate,
pwcxt); break; case T_BitmapIndexScanState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecBitmapIndexScanInitializeWorker((BitmapIndexScanState *) planstate,
pwcxt); break; case T_ForeignScanState: if (planstate->plan->parallel_aware)
ExecForeignScanInitializeWorker((ForeignScanState *) planstate,
pwcxt); break; case T_AppendState: if (planstate->plan->parallel_aware)
ExecAppendInitializeWorker((AppendState *) planstate, pwcxt); break; case T_CustomScanState: if (planstate->plan->parallel_aware)
ExecCustomScanInitializeWorker((CustomScanState *) planstate,
pwcxt); break; case T_BitmapHeapScanState: if (planstate->plan->parallel_aware)
ExecBitmapHeapInitializeWorker((BitmapHeapScanState *) planstate,
pwcxt); break; case T_HashJoinState: if (planstate->plan->parallel_aware)
ExecHashJoinInitializeWorker((HashJoinState *) planstate,
pwcxt); break; case T_HashState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecHashInitializeWorker((HashState *) planstate, pwcxt); break; case T_SortState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecSortInitializeWorker((SortState *) planstate, pwcxt); break; case T_IncrementalSortState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecIncrementalSortInitializeWorker((IncrementalSortState *) planstate,
pwcxt); break; case T_AggState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecAggInitializeWorker((AggState *) planstate, pwcxt); break; case T_MemoizeState: /* even when not parallel-aware, for EXPLAIN ANALYZE */
ExecMemoizeInitializeWorker((MemoizeState *) planstate, pwcxt); break; default: break;
}
/* Report instrumentation data if any instrumentation options are set. */ if (instrumentation != NULL)
ExecParallelReportInstrumentation(queryDesc->planstate,
instrumentation);
/* Report JIT instrumentation data if any */ if (queryDesc->estate->es_jit && jit_instrumentation != NULL)
{
Assert(ParallelWorkerNumber < jit_instrumentation->num_workers);
jit_instrumentation->jit_instr[ParallelWorkerNumber] =
queryDesc->estate->es_jit->instr;
}
/* Must do this after capturing instrumentation. */
ExecutorEnd(queryDesc);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.