diff options
author | David Percy <david.percy@mongodb.com> | 2019-11-13 22:26:52 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-11-13 22:26:52 +0000 |
commit | e75d261790ca1fdbe21afce043af16b552d9a293 (patch) | |
tree | b4558fbfbb694f311522881832c9723b45ca2474 | |
parent | 3ffd21eb0555cf729daf6f5ee9281137058ac9b8 (diff) | |
download | mongo-e75d261790ca1fdbe21afce043af16b552d9a293.tar.gz |
SERVER-38691 Include serverInfo in explain output for aggregation and sharding
-rw-r--r-- | buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards.yml | 2 | ||||
-rw-r--r-- | jstests/aggregation/explain.js | 14 | ||||
-rw-r--r-- | jstests/sharding/explain_cmd.js | 2 | ||||
-rw-r--r-- | src/mongo/db/query/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/query/explain.cpp | 16 | ||||
-rw-r--r-- | src/mongo/db/query/explain.h | 8 | ||||
-rw-r--r-- | src/mongo/db/query/explain_common.cpp | 52 | ||||
-rw-r--r-- | src/mongo/db/query/explain_common.h | 49 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_aggregate.cpp | 5 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_explain.cpp | 2 |
10 files changed, 129 insertions, 22 deletions
diff --git a/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards.yml b/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards.yml index 570dcfd1c78..99104cfca00 100644 --- a/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards.yml +++ b/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards.yml @@ -111,6 +111,8 @@ selector: - jstests/sharding/server_status_crud_metrics.js # Enable after SERVER-31083 is backported and available on 4.2 and 4.0 binaries - jstests/sharding/enable_sharding_with_primary.js + # Enable after SERVER-38691 gets backported to 4.2 and becomes the last stable. + - jstests/sharding/explain_cmd.js executor: config: diff --git a/jstests/aggregation/explain.js b/jstests/aggregation/explain.js index 3e446afe43a..a9c78170afb 100644 --- a/jstests/aggregation/explain.js +++ b/jstests/aggregation/explain.js @@ -1,5 +1,6 @@ -// Tests the behavior of explain() when used with the aggregation -// pipeline. Explain() should not read or modify the plan cache. +// Tests the behavior of explain() when used with the aggregation pipeline. +// - Explain() should not read or modify the plan cache. +// - The result should always include serverInfo. (function() { "use strict"; @@ -13,6 +14,8 @@ let result = coll.explain().aggregate([{$match: {x: 1, y: 1}}]); assert.eq(null, getAggPlanStage(result, "CACHED_PLAN")); + assert(result.hasOwnProperty('serverInfo'), result); + assert.hasFields(result.serverInfo, ['host', 'port', 'version', 'gitVersion']); // At this point, there should be no entries in the plan cache. result = coll.explain().aggregate([{$match: {x: 1, y: 1}}]); @@ -25,4 +28,11 @@ result = coll.explain().aggregate([{$match: {x: 1, y: 1}}]); assert.eq(null, getAggPlanStage(result, "CACHED_PLAN")); + // At the time of this writing there are times when an entire aggregation pipeline can be + // absorbed into the query layer. In these cases we use a different explain mechanism. Using + // $lookup will prevent this optimization and stress an explain implementation in the + // aggregation layer. Test that this implementation also includes serverInfo. + result = coll.explain().aggregate([{$lookup: {from: 'other_coll', pipeline: [], as: 'docs'}}]); + assert(result.hasOwnProperty('serverInfo'), result); + assert.hasFields(result.serverInfo, ['host', 'port', 'version', 'gitVersion']); })(); diff --git a/jstests/sharding/explain_cmd.js b/jstests/sharding/explain_cmd.js index 0b5dcf8bf30..6cf9b78d82a 100644 --- a/jstests/sharding/explain_cmd.js +++ b/jstests/sharding/explain_cmd.js @@ -51,6 +51,8 @@ assert("executionStats" in explain); assert.eq(2, explain.queryPlanner.winningPlan.shards.length); assert.eq(2, explain.executionStats.executionStages.shards.length); + assert("serverInfo" in explain, explain); + assert.hasFields(explain.serverInfo, ['host', 'port', 'version', 'gitVersion']); // An explain of a command that doesn't exist should fail gracefully. explain = db.runCommand({ diff --git a/src/mongo/db/query/SConscript b/src/mongo/db/query/SConscript index f4a37ab200d..30f8745cb9e 100644 --- a/src/mongo/db/query/SConscript +++ b/src/mongo/db/query/SConscript @@ -63,6 +63,7 @@ env.Library( target="query_common", source=[ "collation/collator_factory_icu_decoration.cpp", + "explain_common.cpp", "find_common.cpp", "parsed_distinct.cpp", ], diff --git a/src/mongo/db/query/explain.cpp b/src/mongo/db/query/explain.cpp index 1c9612833de..ac8f29d0bf6 100644 --- a/src/mongo/db/query/explain.cpp +++ b/src/mongo/db/query/explain.cpp @@ -45,6 +45,7 @@ #include "mongo/db/exec/text.h" #include "mongo/db/exec/working_set_common.h" #include "mongo/db/keypattern.h" +#include "mongo/db/query/explain_common.h" #include "mongo/db/query/get_executor.h" #include "mongo/db/query/plan_executor.h" #include "mongo/db/query/plan_summary_stats.h" @@ -732,17 +733,6 @@ void Explain::generateSinglePlanExecutionInfo(const PlanStageStats* stats, stagesBob.doneFast(); } -// static -void Explain::generateServerInfo(BSONObjBuilder* out) { - BSONObjBuilder serverBob(out->subobjStart("serverInfo")); - out->append("host", getHostNameCached()); - out->appendNumber("port", serverGlobalParams.port); - auto&& vii = VersionInfoInterface::instance(); - out->append("version", vii.version()); - out->append("gitVersion", vii.gitVersion()); - serverBob.doneFast(); -} - std::unique_ptr<PlanStageStats> Explain::getWinningPlanTrialStats(PlanExecutor* exec) { // Inspect the tree to see if there is a MultiPlanStage. Plan selection has already happened at // this point, since we have a PlanExecutor. @@ -851,6 +841,8 @@ void Explain::explainPipelineExecutor(PlanExecutor* exec, } *out << "stages" << Value(pps->writeExplainOps(verbosity)); + + explain_common::generateServerInfo(out); } // static @@ -875,7 +867,7 @@ void Explain::explainStages(PlanExecutor* exec, explainStages(exec, collection, verbosity, executePlanStatus, winningPlanTrialStats.get(), out); - generateServerInfo(out); + explain_common::generateServerInfo(out); } // static diff --git a/src/mongo/db/query/explain.h b/src/mongo/db/query/explain.h index 2d736c7e3d0..4f267291757 100644 --- a/src/mongo/db/query/explain.h +++ b/src/mongo/db/query/explain.h @@ -225,14 +225,6 @@ private: ExplainOptions::Verbosity verbosity, boost::optional<long long> totalTimeMillis, BSONObjBuilder* out); - - /** - * Adds the 'serverInfo' explain section to the BSON object being build - * by 'out'. - * - * This is a helper for generating explain BSON. It is used by explainStages(...). - */ - static void generateServerInfo(BSONObjBuilder* out); }; } // namespace diff --git a/src/mongo/db/query/explain_common.cpp b/src/mongo/db/query/explain_common.cpp new file mode 100644 index 00000000000..de9f87be068 --- /dev/null +++ b/src/mongo/db/query/explain_common.cpp @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2019-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/explain_common.h" + +#include "mongo/db/server_options.h" +#include "mongo/util/net/socket_utils.h" +#include "mongo/util/version.h" + +namespace mongo { +namespace explain_common { + +void generateServerInfo(BSONObjBuilder* out) { + BSONObjBuilder serverBob(out->subobjStart("serverInfo")); + out->append("host", getHostNameCached()); + out->appendNumber("port", serverGlobalParams.port); + auto&& vii = VersionInfoInterface::instance(); + out->append("version", vii.version()); + out->append("gitVersion", vii.gitVersion()); + serverBob.doneFast(); +} + +} // namespace explain_common +} // namespace mongo diff --git a/src/mongo/db/query/explain_common.h b/src/mongo/db/query/explain_common.h new file mode 100644 index 00000000000..abff0edecc3 --- /dev/null +++ b/src/mongo/db/query/explain_common.h @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2019-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. + */ + +#pragma once + +#include "mongo/bson/bsonobjbuilder.h" + +namespace mongo { + +/** + * Namespace for static methods that are shared between explain on mongod and on mongos. + */ +namespace explain_common { + +/** + * Adds the 'serverInfo' explain section to the BSON object being built by 'out'. + * + * This section include the host, port, version, and gitVersion. + */ +void generateServerInfo(BSONObjBuilder* out); + +} // namespace explain_common +} // namespace mongo diff --git a/src/mongo/s/commands/cluster_aggregate.cpp b/src/mongo/s/commands/cluster_aggregate.cpp index d58ce76220a..0fab00f2d19 100644 --- a/src/mongo/s/commands/cluster_aggregate.cpp +++ b/src/mongo/s/commands/cluster_aggregate.cpp @@ -52,6 +52,7 @@ #include "mongo/db/pipeline/pipeline.h" #include "mongo/db/query/collation/collator_factory_interface.h" #include "mongo/db/query/cursor_response.h" +#include "mongo/db/query/explain_common.h" #include "mongo/db/query/find_common.h" #include "mongo/db/views/resolved_view.h" #include "mongo/db/views/view.h" @@ -938,6 +939,10 @@ Status ClusterAggregate::runAggregate(OperationContext* opCtx, << AggregationRequest::kMergeByPBRTName << "] cannot be set to 'true' when sent to mongos", !request.needsMerge() && !request.isFromMongos() && !request.mergeByPBRT()); + if (request.getExplain()) { + explain_common::generateServerInfo(result); + } + auto executionNsRoutingInfoStatus = getExecutionNsRoutingInfo(opCtx, namespaces.executionNss); boost::optional<CachedCollectionRoutingInfo> routingInfo; LiteParsedPipeline litePipe(request); diff --git a/src/mongo/s/commands/cluster_explain.cpp b/src/mongo/s/commands/cluster_explain.cpp index 089b7a4221f..7d621438101 100644 --- a/src/mongo/s/commands/cluster_explain.cpp +++ b/src/mongo/s/commands/cluster_explain.cpp @@ -33,6 +33,7 @@ #include "mongo/bson/bsonmisc.h" #include "mongo/db/command_generic_argument.h" #include "mongo/db/commands.h" +#include "mongo/db/query/explain_common.h" #include "mongo/rpc/get_status_from_command_result.h" #include "mongo/s/client/shard_registry.h" #include "mongo/s/commands/cluster_explain.h" @@ -373,6 +374,7 @@ Status ClusterExplain::buildExplainResult(OperationContext* opCtx, buildPlannerInfo(opCtx, shardResults, mongosStageName, out); buildExecStats(shardResults, mongosStageName, millisElapsed, out); + explain_common::generateServerInfo(out); return Status::OK(); } |