summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/plan_cache.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/query/plan_cache.h')
-rw-r--r--src/mongo/db/query/plan_cache.h149
1 files changed, 87 insertions, 62 deletions
diff --git a/src/mongo/db/query/plan_cache.h b/src/mongo/db/query/plan_cache.h
index e1e529d198f..b57fa2015b6 100644
--- a/src/mongo/db/query/plan_cache.h
+++ b/src/mongo/db/query/plan_cache.h
@@ -39,6 +39,7 @@
#include "mongo/db/query/index_tag.h"
#include "mongo/db/query/lru_key_value.h"
#include "mongo/db/query/plan_cache_indexability.h"
+#include "mongo/db/query/plan_ranking_decision.h"
#include "mongo/db/query/query_planner_params.h"
#include "mongo/platform/atomic_word.h"
#include "mongo/stdx/mutex.h"
@@ -49,7 +50,6 @@ namespace mongo {
// A PlanCacheKey is a string-ified version of a query's predicate/projection/sort.
typedef std::string PlanCacheKey;
-struct PlanRankingDecision;
struct QuerySolution;
struct QuerySolutionNode;
@@ -58,16 +58,23 @@ struct QuerySolutionNode;
* feedback is available to anyone who retrieves that query in the future.
*/
struct PlanCacheEntryFeedback {
+ uint64_t estimateObjectSizeInBytes() const {
+ return stats->estimateObjectSizeInBytes() + sizeof(*this);
+ }
+
+ std::unique_ptr<PlanCacheEntryFeedback> clone() const {
+ auto clonedFeedback = stdx::make_unique<PlanCacheEntryFeedback>();
+ clonedFeedback->stats.reset(stats->clone());
+ clonedFeedback->score = score;
+ return clonedFeedback;
+ }
+
// 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;
-
- uint64_t estimateObjectSizeInBytes() const {
- return stats->estimateObjectSizeInBytes() + sizeof(*this);
- }
};
// TODO: Replace with opaque type.
@@ -185,8 +192,7 @@ struct SolutionCacheData {
wholeIXSolnDir(1),
indexFilterApplied(false) {}
- // Make a deep copy.
- SolutionCacheData* clone() const;
+ std::unique_ptr<SolutionCacheData> clone() const;
// For debugging.
std::string toString() const;
@@ -234,28 +240,12 @@ private:
MONGO_DISALLOW_COPYING(CachedSolution);
public:
- CachedSolution(const PlanCacheKey& key, const PlanCacheEntry& entry);
- ~CachedSolution();
+ CachedSolution(const PlanCacheEntry& entry);
- // Owned here.
- std::vector<SolutionCacheData*> plannerData;
-
- // Key used to provide feedback on the entry.
- PlanCacheKey key;
-
- // For debugging.
- std::string toString() const;
+ // Information that can be used by the QueryPlanner to reconstitute the complete execution plan.
+ std::unique_ptr<SolutionCacheData> plannerData;
- // We are extracting just enough information from the canonical
- // query. We could clone the canonical query but the following
- // items are all that is displayed to the user.
- BSONObj query;
- BSONObj sort;
- BSONObj projection;
- BSONObj collation;
-
- // The number of work cycles taken to decide on a winning plan when the plan was first
- // cached.
+ // The number of work cycles taken to decide on a winning plan when the plan was first cached.
size_t decisionWorks;
};
@@ -269,6 +259,54 @@ private:
public:
/**
+ * A description of the query from which a 'PlanCacheEntry' was created.
+ */
+ struct CreatedFromQuery {
+ /**
+ * Returns an estimate of the size of this object, including the memory allocated elsewhere
+ * that it owns, in bytes.
+ */
+ uint64_t estimateObjectSizeInBytes() const;
+
+ std::string debugString() const;
+
+ BSONObj filter;
+ BSONObj sort;
+ BSONObj projection;
+ BSONObj collation;
+ };
+
+ /**
+ * Per-plan cache entry information that is used strictly as debug information (e.g. is intended
+ * for display by the 'planCacheListPlans' command). In order to save memory, this information
+ * is sometimes discarded instead of kept in the plan cache entry. Therefore, this information
+ * may not be used for any purpose outside displaying debug info, such as recovering a plan from
+ * the cache or determining whether or not the cache entry is active.
+ */
+ struct DebugInfo {
+ DebugInfo(CreatedFromQuery createdFromQuery,
+ std::unique_ptr<const PlanRankingDecision> decision,
+ std::vector<std::unique_ptr<PlanCacheEntryFeedback>> feedback);
+
+ /**
+ * Returns an estimate of the size of this object, including the memory allocated elsewhere
+ * that it owns, in bytes.
+ */
+ uint64_t estimateObjectSizeInBytes() const;
+
+ std::unique_ptr<DebugInfo> clone() const;
+
+ CreatedFromQuery createdFromQuery;
+
+ // Information that went into picking the winning plan and also why the other plans lost.
+ // Never nullptr.
+ std::unique_ptr<const PlanRankingDecision> decision;
+
+ // Scores from uses of this cache entry.
+ std::vector<std::unique_ptr<PlanCacheEntryFeedback>> feedback;
+ };
+
+ /**
* Create a new PlanCacheEntry.
* Grabs any planner-specific data required from the solutions.
*/
@@ -285,39 +323,34 @@ public:
*/
PlanCacheEntry* clone() const;
- // For debugging.
- std::string toString() const;
+ std::string debugString() const;
+ // Data provided to the planner to allow it to recreate the solution this entry represents. In
+ // order to return it from the cache for consumption by the 'QueryPlanner', a deep copy is made
+ // and returned inside 'CachedSolution'.
//
- // Planner data
- //
-
- // Data provided to the planner to allow it to recreate the solutions this entry
- // represents. Each SolutionCacheData is fully owned here, so in order to return
- // it from the cache a deep copy is made and returned inside CachedSolution.
+ // The first element of the vector is the cache data associated with the winning plan. The
+ // remaining elements correspond to the rejected plans, sorted by descending score.
const std::vector<std::unique_ptr<const SolutionCacheData>> plannerData;
- // TODO: Do we really want to just hold a copy of the CanonicalQuery? For now we just
- // extract the data we need.
- //
- // Used by the plan cache commands to display an example query
- // of the appropriate shape.
- const BSONObj query;
- const BSONObj sort;
- const BSONObj projection;
- const BSONObj collation;
const Date_t timeOfCreation;
- //
- // Performance stats
- //
+ // The number of work taken to select the winning plan when this plan cache entry was first
+ // created.
+ const size_t decisionWorks;
- // Information that went into picking the winning plan and also why the other plans lost.
- const std::unique_ptr<const PlanRankingDecision> decision;
+ // Optional debug info containing detailed statistics. Includes a description of the query which
+ // resulted in this plan cache's creation as well as runtime stats from the multi-planner trial
+ // period that resulted in this cache entry.
+ //
+ // Once the estimated cumulative size of the mongod's plan caches exceeds a threshold, this
+ // debug info is omitted from new plan cache entries.
+ std::unique_ptr<DebugInfo> debugInfo;
- // Annotations from cached runs. The CachedPlanStage provides these stats about its
- // runs when they complete.
- std::vector<PlanCacheEntryFeedback*> feedback;
+ // An estimate of the size in bytes of this plan cache entry. This is the "deep size",
+ // calculated by recursively incorporating the size of owned objects, the objects that they in
+ // turn own, and so on.
+ const uint64_t estimatedEntrySizeBytes;
/**
* Tracks the approximate cumulative size of the plan cache entries across all the collections.
@@ -329,19 +362,11 @@ private:
* All arguments constructor.
*/
PlanCacheEntry(std::vector<std::unique_ptr<const SolutionCacheData>> plannerData,
- const BSONObj& query,
- const BSONObj& sort,
- const BSONObj& projection,
- const BSONObj& collation,
Date_t timeOfCreation,
- std::unique_ptr<const PlanRankingDecision> decision,
- std::vector<PlanCacheEntryFeedback*> feedback);
+ size_t decisionWorks,
+ std::unique_ptr<DebugInfo> debugInfo);
uint64_t _estimateObjectSizeInBytes() const;
-
- // The total runtime size of the current object in bytes. This is the deep size, obtained by
- // recursively following references to all owned objects.
- const uint64_t _entireObjectSize;
};
/**