summaryrefslogtreecommitdiff
path: root/src/mongo/db/exec/cached_plan.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/exec/cached_plan.cpp')
-rw-r--r--src/mongo/db/exec/cached_plan.cpp43
1 files changed, 22 insertions, 21 deletions
diff --git a/src/mongo/db/exec/cached_plan.cpp b/src/mongo/db/exec/cached_plan.cpp
index 99ce35a7d5e..a65e0639776 100644
--- a/src/mongo/db/exec/cached_plan.cpp
+++ b/src/mongo/db/exec/cached_plan.cpp
@@ -102,7 +102,28 @@ Status CachedPlanStage::pickBestPlan(PlanYieldPolicy* yieldPolicy) {
}
WorkingSetID id = WorkingSet::INVALID_ID;
- PlanStage::StageState state = child()->work(&id);
+ PlanStage::StageState state;
+ try {
+ state = child()->work(&id);
+ } catch (const ExceptionFor<ErrorCodes::QueryExceededMemoryLimitNoDiskUseAllowed>& ex) {
+ // The plan failed by hitting the limit we impose on memory consumption. It's possible
+ // that a different plan is less resource-intensive, so we fall back to replanning the
+ // whole query. We neither evict the existing cache entry nor cache the result of
+ // replanning.
+ LOGV2_DEBUG(20579,
+ 1,
+ "Execution of cached plan failed, falling back to replan. query: "
+ "{query} planSummary: {planSummary} status: {status}",
+ "Execution of cached plan failed, failling back to replan",
+ "query"_attr = redact(_canonicalQuery->toStringShort()),
+ "planSummary"_attr = Explain::getPlanSummary(child().get()),
+ "status"_attr = redact(ex.toStatus()));
+
+ const bool shouldCache = false;
+ return replan(yieldPolicy,
+ shouldCache,
+ str::stream() << "cached plan returned: " << ex.toStatus());
+ }
if (PlanStage::ADVANCED == state) {
// Save result for later.
@@ -136,26 +157,6 @@ Status CachedPlanStage::pickBestPlan(PlanYieldPolicy* yieldPolicy) {
if (!yieldStatus.isOK()) {
return yieldStatus;
}
- } else if (PlanStage::FAILURE == state) {
- // On failure, fall back to replanning the whole query. We neither evict the
- // existing cache entry nor cache the result of replanning.
- BSONObj statusObj = WorkingSetCommon::getStatusMemberDocument(*_ws, id)->toBson();
-
- LOGV2_DEBUG(20579,
- 1,
- "Execution of cached plan failed, falling back to replan. query: "
- "{canonicalQuery_Short} planSummary: {Explain_getPlanSummary_child_get} "
- "status: {statusObj}",
- "canonicalQuery_Short"_attr = redact(_canonicalQuery->toStringShort()),
- "Explain_getPlanSummary_child_get"_attr =
- Explain::getPlanSummary(child().get()),
- "statusObj"_attr = redact(statusObj));
-
- const bool shouldCache = false;
- return replan(yieldPolicy,
- shouldCache,
- str::stream() << "cached plan returned: "
- << WorkingSetCommon::toStatusString(statusObj));
} else {
invariant(PlanStage::NEED_TIME == state);
}