summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/sbe_plan_cache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/query/sbe_plan_cache.cpp')
-rw-r--r--src/mongo/db/query/sbe_plan_cache.cpp91
1 files changed, 65 insertions, 26 deletions
diff --git a/src/mongo/db/query/sbe_plan_cache.cpp b/src/mongo/db/query/sbe_plan_cache.cpp
index 70d864e7074..b699387cc47 100644
--- a/src/mongo/db/query/sbe_plan_cache.cpp
+++ b/src/mongo/db/query/sbe_plan_cache.cpp
@@ -31,7 +31,7 @@
#include "mongo/db/query/sbe_plan_cache.h"
-#include "mongo/db/query/util/memory_util.h"
+#include "mongo/db/query/plan_cache_size_parameter.h"
#include "mongo/db/server_options.h"
#include "mongo/logv2/log.h"
#include "mongo/util/processinfo.h"
@@ -42,23 +42,71 @@ namespace {
const auto sbePlanCacheDecoration =
ServiceContext::declareDecoration<std::unique_ptr<sbe::PlanCache>>();
+size_t convertToSizeInBytes(const plan_cache_util::PlanCacheSizeParameter& param) {
+ constexpr size_t kBytesInMB = 1014 * 1024;
+ constexpr size_t kMBytesInGB = 1014;
+
+ double sizeInMB = param.size;
+
+ switch (param.units) {
+ case plan_cache_util::PlanCacheSizeUnits::kPercent:
+ sizeInMB *= ProcessInfo::getMemSizeMB() / 100.0;
+ break;
+ case plan_cache_util::PlanCacheSizeUnits::kMB:
+ break;
+ case plan_cache_util::PlanCacheSizeUnits::kGB:
+ sizeInMB *= kMBytesInGB;
+ break;
+ }
+
+ return static_cast<size_t>(sizeInMB * kBytesInMB);
+}
+
+/**
+ * Sets upper size limit on the PlanCache size to 500GB or 25% of the system's memory, whichever is
+ * smaller.
+ */
+size_t capPlanCacheSize(size_t planCacheSize) {
+ constexpr size_t kBytesInGB = 1024 * 1024 * 1024;
+
+ // Maximum size of the plan cache expressed in bytes.
+ constexpr size_t kMaximumPlanCacheSize = 500 * kBytesInGB;
+
+ // Maximum size of the plan cache expressed as a share of the memory available to the process.
+ const plan_cache_util::PlanCacheSizeParameter limitToProcessSize{
+ 25, plan_cache_util::PlanCacheSizeUnits::kPercent};
+ const size_t limitToProcessSizeInBytes = convertToSizeInBytes(limitToProcessSize);
+
+ // The size will be capped by the minimum of the two values defined above.
+ const size_t maxPlanCacheSize = std::min(kMaximumPlanCacheSize, limitToProcessSizeInBytes);
+
+ if (planCacheSize > maxPlanCacheSize) {
+ planCacheSize = maxPlanCacheSize;
+ LOGV2_DEBUG(6007000,
+ 1,
+ "The plan cache size has been capped",
+ "maxPlanCacheSize"_attr = maxPlanCacheSize);
+ }
+
+ return planCacheSize;
+}
+
+size_t getPlanCacheSizeInBytes(const plan_cache_util::PlanCacheSizeParameter& param) {
+ size_t planCacheSize = convertToSizeInBytes(param);
+ uassert(5968001,
+ "Cache size must be at least 1KB * number of cores",
+ planCacheSize >= 1024 * ProcessInfo::getNumCores());
+ return capPlanCacheSize(planCacheSize);
+}
class PlanCacheOnParamChangeUpdaterImpl final : public plan_cache_util::OnParamChangeUpdater {
public:
- void updateCacheSize(ServiceContext* serviceCtx, memory_util::MemorySize memSize) final {
+ void updateCacheSize(ServiceContext* serviceCtx,
+ plan_cache_util::PlanCacheSizeParameter parameter) final {
if (feature_flags::gFeatureFlagSbePlanCache.isEnabledAndIgnoreFCV()) {
- auto newSizeBytes = memory_util::getRequestedMemSizeInBytes(memSize);
- auto cappedCacheSize = memory_util::capMemorySize(newSizeBytes /*requestedSizeBytes*/,
- 500 /*maximumSizeGB*/,
- 25 /*percentTotalSystemMemory*/);
- if (cappedCacheSize < newSizeBytes) {
- LOGV2_DEBUG(6007001,
- 1,
- "The plan cache size has been capped",
- "cappedSize"_attr = cappedCacheSize);
- }
+ auto size = getPlanCacheSizeInBytes(parameter);
auto& globalPlanCache = sbePlanCacheDecoration(serviceCtx);
- globalPlanCache->reset(cappedCacheSize);
+ globalPlanCache->reset(size);
}
}
@@ -76,21 +124,12 @@ ServiceContext::ConstructorActionRegisterer planCacheRegisterer{
std::make_unique<PlanCacheOnParamChangeUpdaterImpl>();
if (feature_flags::gFeatureFlagSbePlanCache.isEnabledAndIgnoreFCV()) {
- auto status = memory_util::MemorySize::parse(planCacheSize.get());
+ auto status = plan_cache_util::PlanCacheSizeParameter::parse(planCacheSize.get());
uassertStatusOK(status);
- auto size = memory_util::getRequestedMemSizeInBytes(status.getValue());
- auto cappedCacheSize = memory_util::capMemorySize(size /*requestedSizeBytes*/,
- 500 /*maximumSizeGB*/,
- 25 /*percentTotalSystemMemory*/);
- if (cappedCacheSize < size) {
- LOGV2_DEBUG(6007000,
- 1,
- "The plan cache size has been capped",
- "cappedSize"_attr = cappedCacheSize);
- }
+
+ auto size = getPlanCacheSizeInBytes(status.getValue());
auto& globalPlanCache = sbePlanCacheDecoration(serviceCtx);
- globalPlanCache =
- std::make_unique<sbe::PlanCache>(cappedCacheSize, ProcessInfo::getNumCores());
+ globalPlanCache = std::make_unique<sbe::PlanCache>(size, ProcessInfo::getNumCores());
}
}};