diff options
author | Nicholas Zolnierz <nicholas.zolnierz@mongodb.com> | 2022-08-03 16:08:42 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-08-03 17:22:30 +0000 |
commit | c9bbd1cfae470f2b3229e69957f512d2a2db6663 (patch) | |
tree | 1176c9ce875b1abfd346b1614c96608d6a7ee434 /src/mongo/db/query | |
parent | 970a89221d0520693bc64bb33df6b1bf66d7c56d (diff) | |
download | mongo-c9bbd1cfae470f2b3229e69957f512d2a2db6663.tar.gz |
SERVER-62042 Consolidate query optimization and execution control into a single knob
Diffstat (limited to 'src/mongo/db/query')
-rw-r--r-- | src/mongo/db/query/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/query/canonical_query.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/query/canonical_query_encoder_test.cpp | 42 | ||||
-rw-r--r-- | src/mongo/db/query/framework_control.cpp | 45 | ||||
-rw-r--r-- | src/mongo/db/query/plan_cache_key_info_test.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/query/query_knobs.idl | 44 | ||||
-rw-r--r-- | src/mongo/db/query/query_planner_columnar_test.cpp | 3 |
7 files changed, 102 insertions, 42 deletions
diff --git a/src/mongo/db/query/SConscript b/src/mongo/db/query/SConscript index f25c387d64f..bb5e3047085 100644 --- a/src/mongo/db/query/SConscript +++ b/src/mongo/db/query/SConscript @@ -261,6 +261,7 @@ env.Library( target="query_knobs", source=[ 'ce_mode_parameter.cpp', + 'framework_control.cpp', 'plan_cache_size_parameter.cpp', 'query_feature_flags.idl', 'query_knobs.idl', diff --git a/src/mongo/db/query/canonical_query.cpp b/src/mongo/db/query/canonical_query.cpp index f6f69af1605..bbd7c68a21b 100644 --- a/src/mongo/db/query/canonical_query.cpp +++ b/src/mongo/db/query/canonical_query.cpp @@ -191,7 +191,9 @@ Status CanonicalQuery::init(OperationContext* opCtx, _findCommand = std::move(findCommand); _canHaveNoopMatchNodes = canHaveNoopMatchNodes; - _forceClassicEngine = internalQueryForceClassicEngine.load(); + _forceClassicEngine = ServerParameterSet::getNodeParameterSet() + ->get<QueryFrameworkControl>("internalQueryFrameworkControl") + ->_data.get() == QueryFrameworkControlEnum::kForceClassicEngine; auto validStatus = isValid(root.get(), *_findCommand); if (!validStatus.isOK()) { diff --git a/src/mongo/db/query/canonical_query_encoder_test.cpp b/src/mongo/db/query/canonical_query_encoder_test.cpp index 359a50ab625..6b814fd91b9 100644 --- a/src/mongo/db/query/canonical_query_encoder_test.cpp +++ b/src/mongo/db/query/canonical_query_encoder_test.cpp @@ -172,8 +172,9 @@ TEST(CanonicalQueryEncoderTest, ComputeKey) { // The computed key depends on which execution engine is enabled. As such, we disable SBE for // this test so that the test doesn't break should the default value of - // 'internalQueryForceClassicEngine' change in the future. - RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", true); + // 'internalQueryFrameworkControl' change in the future. + RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl", + "forceClassicEngine"); // No sorts testComputeKey("{}", "{}", "{}", "an@f"); @@ -247,8 +248,9 @@ TEST(CanonicalQueryEncoderTest, ComputeKey) { TEST(CanonicalQueryEncoderTest, EncodeNotEqualNullPredicates) { // The computed key depends on which execution engine is enabled. As such, we disable SBE for // this test so that the test doesn't break should the default value of - // 'internalQueryForceClassicEngine' change in the future. - RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", true); + // 'internalQueryFrameworkControl' change in the future. + RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl", + "forceClassicEngine"); // With '$eq', '$gte', and '$lte' negation comparison to 'null'. testComputeKey("{a: {$not: {$eq: null}}}", "{}", "{_id: 0, a: 1}", "ntnot_eq_null[eqa]|a@f"); @@ -268,8 +270,9 @@ TEST(CanonicalQueryEncoderTest, EncodeNotEqualNullPredicates) { TEST(CanonicalQueryEncoderTest, ComputeKeyEscaped) { // The computed key depends on which execution engine is enabled. As such, we disable SBE for // this test so that the test doesn't break should the default value of - // 'internalQueryForceClassicEngine' change in the future. - RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", true); + // 'internalQueryFrameworkControl' change in the future. + RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl", + "forceClassicEngine"); // Field name in query. testComputeKey("{'a,[]~|-<>': 1}", "{}", "{}", "eqa\\,\\[\\]\\~\\|\\-<>@f"); @@ -304,8 +307,9 @@ TEST(CanonicalQueryEncoderTest, ComputeKeyGeoWithin) { TEST(CanonicalQueryEncoderTest, ComputeKeyGeoNear) { // The computed key depends on which execution engine is enabled. As such, we disable SBE for // this test so that the test doesn't break should the default value of - // 'internalQueryForceClassicEngine' change in the future. - RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", true); + // 'internalQueryFrameworkControl' change in the future. + RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl", + "forceClassicEngine"); testComputeKey("{a: {$near: [0,0], $maxDistance:0.3 }}", "{}", "{}", "gnanrfl@f"); testComputeKey("{a: {$nearSphere: [0,0], $maxDistance: 0.31 }}", "{}", "{}", "gnanssp@f"); @@ -320,7 +324,8 @@ TEST(CanonicalQueryEncoderTest, ComputeKeyGeoNear) { TEST(CanonicalQueryEncoderTest, ComputeKeyRegexDependsOnFlags) { // The computed key depends on which execution engine is enabled. As such, we enable SBE for // this test in order to ensure that we have coverage for both SBE and the classic engine. - RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", false); + RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl", + "trySbeEngine"); testComputeKey("{a: {$regex: \"sometext\"}}", "{}", "{}", "rea@t"); testComputeKey("{a: {$regex: \"sometext\", $options: \"\"}}", "{}", "{}", "rea@t"); @@ -353,8 +358,9 @@ TEST(CanonicalQueryEncoderTest, ComputeKeyRegexDependsOnFlags) { TEST(CanonicalQueryEncoderTest, ComputeKeyMatchInDependsOnPresenceOfRegexAndFlags) { // The computed key depends on which execution engine is enabled. As such, we disable SBE for // this test so that the test doesn't break should the default value of - // 'internalQueryForceClassicEngine' change in the future. - RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", true); + // 'internalQueryFrameworkControl' change in the future. + RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl", + "forceClassicEngine"); // Test that an $in containing a single regex is unwrapped to $regex. testComputeKey("{a: {$in: [/foo/]}}", "{}", "{}", "rea@f"); @@ -403,8 +409,9 @@ TEST(CanonicalQueryEncoderTest, ComputeKeyMatchInDependsOnPresenceOfRegexAndFlag TEST(CanonicalQueryEncoderTest, CheckCollationIsEncoded) { // The computed key depends on which execution engine is enabled. As such, we disable SBE for // this test so that the test doesn't break should the default value of - // 'internalQueryForceClassicEngine' change in the future. - RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", true); + // 'internalQueryFrameworkControl' change in the future. + RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl", + "forceClassicEngine"); unique_ptr<CanonicalQuery> cq(canonicalize( fromjson("{a: 1, b: 1}"), {}, {}, fromjson("{locale: 'mock_reverse_string'}"))); @@ -416,7 +423,8 @@ TEST(CanonicalQueryEncoderTest, ComputeKeySBE) { // Generated cache keys should be treated as opaque to the user. // SBE must be enabled in order to generate SBE plan cache keys. - RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", false); + RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl", + "trySbeEngine"); RAIIServerParameterControllerForTest controllerSBEPlanCache("featureFlagSbeFull", true); @@ -534,7 +542,8 @@ TEST(CanonicalQueryEncoderTest, ComputeKeySBE) { TEST(CanonicalQueryEncoderTest, ComputeKeySBEWithPipeline) { // SBE must be enabled in order to generate SBE plan cache keys. - RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", false); + RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl", + "trySbeEngine"); RAIIServerParameterControllerForTest controllerSBEPlanCache("featureFlagSbeFull", true); @@ -595,7 +604,8 @@ TEST(CanonicalQueryEncoderTest, ComputeKeySBEWithPipeline) { TEST(CanonicalQueryEncoderTest, ComputeKeySBEWithReadConcern) { // SBE must be enabled in order to generate SBE plan cache keys. - RAIIServerParameterControllerForTest controllerSBE("internalQueryForceClassicEngine", false); + RAIIServerParameterControllerForTest controllerSBE("internalQueryFrameworkControl", + "trySbeEngine"); RAIIServerParameterControllerForTest controllerSBEPlanCache("featureFlagSbeFull", true); const auto sbeEncodingWithoutReadConcernAvailable = diff --git a/src/mongo/db/query/framework_control.cpp b/src/mongo/db/query/framework_control.cpp new file mode 100644 index 00000000000..cd35264a9b3 --- /dev/null +++ b/src/mongo/db/query/framework_control.cpp @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2022-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include "mongo/platform/basic.h" + +#include "mongo/db/query/query_knobs_gen.h" + +namespace mongo { + +void QueryFrameworkControl::append(OperationContext*, BSONObjBuilder& b, const std::string& name) { + b << name << QueryFrameworkControl_serializer(_data.get()); +} + +Status QueryFrameworkControl::setFromString(const std::string& value) { + _data = QueryFrameworkControl_parse(IDLParserContext("internalQueryFrameworkControl"), value); + return Status::OK(); +} + +} // namespace mongo diff --git a/src/mongo/db/query/plan_cache_key_info_test.cpp b/src/mongo/db/query/plan_cache_key_info_test.cpp index 7235386e7f4..824fdf9dc37 100644 --- a/src/mongo/db/query/plan_cache_key_info_test.cpp +++ b/src/mongo/db/query/plan_cache_key_info_test.cpp @@ -422,8 +422,9 @@ TEST(PlanCacheKeyInfoTest, DifferentQueryEngines) { // Helper to construct a plan cache key given the 'forceClassicEngine' flag. auto constructPlanCacheKey = [&](bool forceClassicEngine) { - RAIIServerParameterControllerForTest controller{"internalQueryForceClassicEngine", - forceClassicEngine}; + RAIIServerParameterControllerForTest controller{"internalQueryFrameworkControl", + forceClassicEngine ? "forceClassicEngine" + : "trySbeEngine"}; const auto queryStr = "{a: 0}"; unique_ptr<CanonicalQuery> cq(canonicalize(queryStr)); return makeKey(*cq, indexCores); diff --git a/src/mongo/db/query/query_knobs.idl b/src/mongo/db/query/query_knobs.idl index 831334ed790..422ffea63ff 100644 --- a/src/mongo/db/query/query_knobs.idl +++ b/src/mongo/db/query/query_knobs.idl @@ -35,6 +35,21 @@ global: - "mongo/platform/atomic_proxy.h" - "mongo/platform/atomic_word.h" +enums: + QueryFrameworkControl: + description: "Enum for possible values of internalQueryFrameworkControl." + type: string + values: + # Force the classic query engine for all queries. + kForceClassicEngine: "forceClassicEngine" + # Attempt to use SBE for eligible queries, otherwise fallback to the classic engine. + kTrySbeEngine: "trySbeEngine" + # Attempt to use the Bonsai optimizer and lower to SBE for eligible queries, otherwise + # fallback to "trySbeEngine". + kTryBonsai: "tryBonsai" + # Force the Bonsai optimizer for all queries. + kForceBonsai: "forceBonsai" + server_parameters: # @@ -656,14 +671,6 @@ server_parameters: default: false on_update: plan_cache_util::clearSbeCacheOnParameterChange - internalQueryForceClassicEngine: - description: "If true, the system will use the classic execution engine for all queries, - otherwise eligible queries will execute using the SBE execution engine." - set_at: [ startup, runtime ] - cpp_varname: "internalQueryForceClassicEngine" - cpp_vartype: AtomicWord<bool> - default: false - internalQueryAppendIdToSetWindowFieldsSort: description: "If true, appends _id to the sort stage generated by desugaring $setWindowFields to ensure deterministic sort order." @@ -726,14 +733,6 @@ server_parameters: validator: callback: ce::validateCEMode - internalQueryEnableCascadesOptimizer: - description: "Set to use the new optimizer path, must be used in conjunction with the feature - flag." - set_at: [ startup, runtime ] - cpp_varname: "internalQueryEnableCascadesOptimizer" - cpp_vartype: AtomicWord<bool> - default: true - internalCascadesOptimizerDisableScan: description: "Disable full collection scans in the Cascades optimizer." set_at: [ startup, runtime ] @@ -784,13 +783,14 @@ server_parameters: cpp_vartype: AtomicWord<bool> default: false - internalQueryForceCommonQueryFramework: - description: "Set to always use the bonsai optimizer, regardless of the query." + internalQueryFrameworkControl: + description: "Knob to control the optimizer/execution engine to use." set_at: [ startup, runtime ] - cpp_varname: "internalQueryForceCommonQueryFramework" - cpp_vartype: AtomicWord<bool> - test_only: true - default: false + cpp_class: + name: QueryFrameworkControl + data: synchronized_value<QueryFrameworkControlEnum> + default: + expr: QueryFrameworkControlEnum::kTryBonsai internalQueryCollectionMaxNoOfDocumentsToChooseHashJoin: description: "Up to what number of documents do we choose the hash join algorithm when $lookup diff --git a/src/mongo/db/query/query_planner_columnar_test.cpp b/src/mongo/db/query/query_planner_columnar_test.cpp index aeb3f26b69f..f576e8f6cd5 100644 --- a/src/mongo/db/query/query_planner_columnar_test.cpp +++ b/src/mongo/db/query/query_planner_columnar_test.cpp @@ -85,7 +85,8 @@ protected: private: // SBE must be enabled in order to test columnar indexes. - RAIIServerParameterControllerForTest _controllerSBE{"internalQueryForceClassicEngine", false}; + RAIIServerParameterControllerForTest _controllerSBE{"internalQueryFrameworkControl", + "trySbeEngine"}; }; TEST_F(QueryPlannerColumnarTest, InclusionProjectionUsesColumnarIndex) { |