mirror of https://github.com/citusdata/citus.git
replan fastpath queries instead of rerouting them for the sake of clean code
parent
6b0f64e0b2
commit
b3500194fc
|
@ -62,7 +62,7 @@ static void CitusBeginModifyScan(CustomScanState *node, EState *estate, int efla
|
|||
static void CitusPreExecScan(CitusScanState *scanState);
|
||||
static bool ModifyJobNeedsEvaluation(Job *workerJob);
|
||||
static void RegenerateTaskForFasthPathQuery(Job *workerJob);
|
||||
static DistributedPlan * RePlanNonFastPathQuery(DistributedPlan *distributedPlan);
|
||||
static DistributedPlan * RePlanTopLevelQuery(DistributedPlan *distributedPlan);
|
||||
static void RegenerateTaskListForInsert(Job *workerJob);
|
||||
static DistributedPlan * CopyDistributedPlanWithoutCache(
|
||||
DistributedPlan *originalDistributedPlan);
|
||||
|
@ -72,7 +72,6 @@ static void SetJobColocationId(Job *job);
|
|||
static void EnsureForceDelegationDistributionKey(Job *job);
|
||||
static void EnsureAnchorShardsInJobExist(Job *job);
|
||||
static bool AnchorShardsInTaskListExist(List *taskList);
|
||||
static void TryToRerouteFastPathModifyQuery(Job *job);
|
||||
|
||||
|
||||
/* create custom scan methods for all executors */
|
||||
|
@ -413,27 +412,16 @@ CitusBeginModifyScan(CustomScanState *node, EState *estate, int eflags)
|
|||
AcquireMetadataLocks(workerJob->taskList);
|
||||
|
||||
/*
|
||||
* In case of a split, the shard might no longer be available. In that
|
||||
* case try to reroute. We reroute missing shards for fast-path queries.
|
||||
* And we have to replan for non-fastpath queries as pruning directly depends
|
||||
* on postgres planner. (Might be optimized if we have enough info fed from
|
||||
* planning phase. That way, we can recompute tasks similarly but it is more complex.)
|
||||
*/
|
||||
if (!AnchorShardsInTaskListExist(workerJob->taskList))
|
||||
{
|
||||
if (currentPlan->fastPathRouterPlan)
|
||||
{
|
||||
TryToRerouteFastPathModifyQuery(workerJob);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* in case of a split, the shard might no longer be available. In that case,
|
||||
* we have to replan top level query to prevent unfriendly 'missing shards' message.
|
||||
*
|
||||
* we should only replan if we have valid topLevelQueryContext which means our plan
|
||||
* is top level plan (not a subplan)
|
||||
* is top level plan (not a subplan).
|
||||
*/
|
||||
if (originalDistributedPlan->topLevelQueryContext)
|
||||
if (!AnchorShardsInTaskListExist(workerJob->taskList) &&
|
||||
originalDistributedPlan->topLevelQueryContext)
|
||||
{
|
||||
DistributedPlan *newDistributedPlan = RePlanNonFastPathQuery(
|
||||
DistributedPlan *newDistributedPlan = RePlanTopLevelQuery(
|
||||
originalDistributedPlan);
|
||||
scanState->distributedPlan = newDistributedPlan;
|
||||
|
||||
|
@ -445,8 +433,6 @@ CitusBeginModifyScan(CustomScanState *node, EState *estate, int eflags)
|
|||
CitusBeginModifyScan((CustomScanState *) scanState, estate, eflags);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ensure there is no invalid shard */
|
||||
EnsureAnchorShardsInJobExist(workerJob);
|
||||
|
@ -485,27 +471,6 @@ CitusBeginModifyScan(CustomScanState *node, EState *estate, int eflags)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* TryToRerouteFastPathModifyQuery tries to reroute non-existent shards in given job if it finds any such shard,
|
||||
* only for fastpath queries.
|
||||
*
|
||||
* Should only be called if the job belongs to a fastpath modify query
|
||||
*/
|
||||
static void
|
||||
TryToRerouteFastPathModifyQuery(Job *job)
|
||||
{
|
||||
if (job->jobQuery->commandType == CMD_INSERT)
|
||||
{
|
||||
RegenerateTaskListForInsert(job);
|
||||
}
|
||||
else
|
||||
{
|
||||
RegenerateTaskForFasthPathQuery(job);
|
||||
RebuildQueryStrings(job);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* EnsureAnchorShardsInJobExist ensures all shards are valid in job.
|
||||
* If it finds a non-existent shard in given job, it throws an error.
|
||||
|
@ -687,17 +652,14 @@ RegenerateTaskForFasthPathQuery(Job *workerJob)
|
|||
|
||||
|
||||
/*
|
||||
* RePlanNonFastPathQuery replans the initial query, which is stored in the distributed
|
||||
* RePlanTopLevelQuery replans the initial query, which is stored in the distributed
|
||||
* plan, at the start of the planning.
|
||||
*
|
||||
* That method should only be used when we detect any missing shard at execution
|
||||
* phase.
|
||||
* That method is supposed to be used when we detect any missing shard just before execution.
|
||||
*/
|
||||
static DistributedPlan *
|
||||
RePlanNonFastPathQuery(DistributedPlan *oldPlan)
|
||||
RePlanTopLevelQuery(DistributedPlan *oldPlan)
|
||||
{
|
||||
Assert(!oldPlan->fastPathRouterPlan);
|
||||
|
||||
/* extract top level query info from the TopLevelQueryContext stored in the old plan */
|
||||
TopLevelQueryContext *topLevelQueryContext = oldPlan->topLevelQueryContext;
|
||||
|
||||
|
|
Loading…
Reference in New Issue