diff options
-rw-r--r-- | src/mongo/db/commands/plan_cache_commands.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/exec/cached_plan.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/query/plan_cache.cpp | 19 | ||||
-rw-r--r-- | src/mongo/db/query/plan_cache.h | 30 |
4 files changed, 13 insertions, 44 deletions
diff --git a/src/mongo/db/commands/plan_cache_commands.cpp b/src/mongo/db/commands/plan_cache_commands.cpp index 1210588d066..3c1d6a00a6a 100644 --- a/src/mongo/db/commands/plan_cache_commands.cpp +++ b/src/mongo/db/commands/plan_cache_commands.cpp @@ -425,7 +425,7 @@ Status PlanCacheListPlans::list(OperationContext* opCtx, BSONArrayBuilder scoresBob(feedbackBob.subarrayStart("scores")); for (size_t i = 0; i < entry->feedback.size(); ++i) { BSONObjBuilder scoreBob(scoresBob.subobjStart()); - scoreBob.append("score", entry->feedback[i]->score); + scoreBob.append("score", entry->feedback[i]); } scoresBob.doneFast(); } diff --git a/src/mongo/db/exec/cached_plan.cpp b/src/mongo/db/exec/cached_plan.cpp index 33a9759f9a8..ef3bc771b64 100644 --- a/src/mongo/db/exec/cached_plan.cpp +++ b/src/mongo/db/exec/cached_plan.cpp @@ -322,12 +322,10 @@ const SpecificStats* CachedPlanStage::getSpecificStats() const { } void CachedPlanStage::updatePlanCache() { - std::unique_ptr<PlanCacheEntryFeedback> feedback = stdx::make_unique<PlanCacheEntryFeedback>(); - feedback->stats = getStats(); - feedback->score = PlanRanker::scoreTree(feedback->stats->children[0].get()); + const double score = PlanRanker::scoreTree(getStats()->children[0].get()); PlanCache* cache = _collection->infoCache()->getPlanCache(); - Status fbs = cache->feedback(*_canonicalQuery, feedback.release()); + Status fbs = cache->feedback(*_canonicalQuery, score); if (!fbs.isOK()) { LOG(5) << _canonicalQuery->ns() << ": Failed to update cache with feedback: " << redact(fbs) << " - " diff --git a/src/mongo/db/query/plan_cache.cpp b/src/mongo/db/query/plan_cache.cpp index f132dc077b9..ac5015b08d1 100644 --- a/src/mongo/db/query/plan_cache.cpp +++ b/src/mongo/db/query/plan_cache.cpp @@ -411,9 +411,6 @@ PlanCacheEntry::PlanCacheEntry(const std::vector<QuerySolution*>& solutions, } PlanCacheEntry::~PlanCacheEntry() { - for (size_t i = 0; i < feedback.size(); ++i) { - delete feedback[i]; - } for (size_t i = 0; i < plannerData.size(); ++i) { delete plannerData[i]; } @@ -439,12 +436,8 @@ PlanCacheEntry* PlanCacheEntry::clone() const { entry->works = works; // Copy performance stats. - for (size_t i = 0; i < feedback.size(); ++i) { - PlanCacheEntryFeedback* fb = new PlanCacheEntryFeedback(); - fb->stats.reset(feedback[i]->stats->clone()); - fb->score = feedback[i]->score; - entry->feedback.push_back(fb); - } + entry->feedback = feedback; + return entry; } @@ -923,11 +916,7 @@ PlanCache::GetResult PlanCache::get(const PlanCacheKey& key) const { return {state, stdx::make_unique<CachedSolution>(key, *entry)}; } -Status PlanCache::feedback(const CanonicalQuery& cq, PlanCacheEntryFeedback* feedback) { - if (NULL == feedback) { - return Status(ErrorCodes::BadValue, "feedback is NULL"); - } - std::unique_ptr<PlanCacheEntryFeedback> autoFeedback(feedback); +Status PlanCache::feedback(const CanonicalQuery& cq, double score) { PlanCacheKey ck = computeKey(cq); stdx::lock_guard<stdx::mutex> cacheLock(_cacheMutex); @@ -940,7 +929,7 @@ Status PlanCache::feedback(const CanonicalQuery& cq, PlanCacheEntryFeedback* fee // We store up to a constant number of feedback entries. if (entry->feedback.size() < static_cast<size_t>(internalQueryCacheFeedbacksStored.load())) { - entry->feedback.push_back(autoFeedback.release()); + entry->feedback.push_back(score); } return Status::OK(); diff --git a/src/mongo/db/query/plan_cache.h b/src/mongo/db/query/plan_cache.h index b0b767c13ea..159b724df04 100644 --- a/src/mongo/db/query/plan_cache.h +++ b/src/mongo/db/query/plan_cache.h @@ -50,22 +50,6 @@ struct QuerySolution; struct QuerySolutionNode; /** - * When the CachedPlanStage runs a cached query, it can provide feedback to the cache. This - * feedback is available to anyone who retrieves that query in the future. - */ -struct PlanCacheEntryFeedback { - // How well did the cached plan perform? - std::unique_ptr<PlanStageStats> stats; - - // The "goodness" score produced by the plan ranker - // corresponding to 'stats'. - double score; -}; - -// TODO: Replace with opaque type. -typedef std::string PlanID; - -/** * A PlanCacheIndexTree is the meaty component of the data * stored in SolutionCacheData. It is a tree structure with * index tags that indicates to the access planner which indices @@ -283,9 +267,8 @@ public: // the other plans lost. std::unique_ptr<PlanRankingDecision> decision; - // Annotations from cached runs. The CachedPlanStage provides these stats about its - // runs when they complete. - std::vector<PlanCacheEntryFeedback*> feedback; + // Scores from uses of this cache entry. + std::vector<double> feedback; // Whether or not the cache entry is active. Inactive cache entries should not be used for // planning. @@ -407,10 +390,9 @@ public: /** * When the CachedPlanStage runs a plan out of the cache, we want to record data about the - * plan's performance. The CachedPlanStage calls feedback(...) after executing the cached - * plan for a trial period in order to do this. - * - * Cache takes ownership of 'feedback'. + * plan's performance. The CachedPlanStage calls feedback(...) after executing the cached + * plan for a trial period in order to do this. Currently, the only feedback metric recorded is + * the score associated with the cached plan trial period. * * If the entry corresponding to 'cq' isn't in the cache anymore, the feedback is ignored * and an error Status is returned. @@ -418,7 +400,7 @@ public: * If the entry corresponding to 'cq' still exists, 'feedback' is added to the run * statistics about the plan. Status::OK() is returned. */ - Status feedback(const CanonicalQuery& cq, PlanCacheEntryFeedback* feedback); + Status feedback(const CanonicalQuery& cq, double score); /** * Remove the entry corresponding to 'ck' from the cache. Returns Status::OK() if the plan |