diff options
author | David Percy <david.percy@mongodb.com> | 2019-11-19 19:30:18 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-11-19 19:30:18 +0000 |
commit | 67f33c1ea3d2f57c6a3fbe29ab2becc122b7b14f (patch) | |
tree | 1fe2d12aad8e43e71012e05bf690eeddc1caeba8 | |
parent | ee889638f23977fdb89bc4c2be2cbedfc6fd789c (diff) | |
download | mongo-67f33c1ea3d2f57c6a3fbe29ab2becc122b7b14f.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/commands/run_aggregate.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/query/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/query/explain.cpp | 14 | ||||
-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 |
11 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 4e8acf88b53..63b464c161e 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 @@ -117,6 +117,8 @@ selector: # Assumes shard doesn't refresh after a successful splitChunk (which it does # in 3.4) - jstests/sharding/major_version_check.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..5923063b217 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'), JSON.stringify(result, null, 4)); + 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'), JSON.stringify(result, null, 4)); + assert.hasFields(result.serverInfo, ['host', 'port', 'version', 'gitVersion']); })(); diff --git a/jstests/sharding/explain_cmd.js b/jstests/sharding/explain_cmd.js index 3293c167db1..b52f24c6b6a 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); + 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/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp index a89f5ce6c20..64402c4e101 100644 --- a/src/mongo/db/commands/run_aggregate.cpp +++ b/src/mongo/db/commands/run_aggregate.cpp @@ -54,6 +54,7 @@ #include "mongo/db/pipeline/pipeline_d.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/query/get_executor.h" #include "mongo/db/query/plan_summary_stats.h" @@ -552,6 +553,7 @@ Status runAggregate(OperationContext* opCtx, // If both explain and cursor are specified, explain wins. if (expCtx->explain) { + explain_common::generateServerInfo(&result); result << "stages" << Value(unownedPipeline->writeExplainOps(*expCtx->explain)); } else { // Cursor must be specified, if explain is not. diff --git a/src/mongo/db/query/SConscript b/src/mongo/db/query/SConscript index 90203d05847..8558b7dd553 100644 --- a/src/mongo/db/query/SConscript +++ b/src/mongo/db/query/SConscript @@ -100,6 +100,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 ed32b5ac07d..8e194484497 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" @@ -686,17 +687,6 @@ void Explain::generateExecStats(PlanStageStats* stats, } // 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(); -} - -// static void Explain::explainStages(PlanExecutor* exec, const Collection* collection, ExplainOptions::Verbosity verbosity, @@ -797,7 +787,7 @@ void Explain::explainStages(PlanExecutor* exec, execBob.doneFast(); } - generateServerInfo(out); + explain_common::generateServerInfo(out); } // static diff --git a/src/mongo/db/query/explain.h b/src/mongo/db/query/explain.h index 8aa56a08194..d67c299ecb0 100644 --- a/src/mongo/db/query/explain.h +++ b/src/mongo/db/query/explain.h @@ -171,14 +171,6 @@ private: ExplainOptions::Verbosity verbosity, BSONObjBuilder* out, boost::optional<long long> totalTimeMillis); - - /** - * 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..de561c0f079 --- /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/sock.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 36259d4a0ba..b43c1463a37 100644 --- a/src/mongo/s/commands/cluster_aggregate.cpp +++ b/src/mongo/s/commands/cluster_aggregate.cpp @@ -48,6 +48,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" @@ -658,6 +659,10 @@ Status ClusterAggregate::runAggregate(OperationContext* opCtx, const AggregationRequest& request, BSONObj cmdObj, BSONObjBuilder* result) { + if (request.getExplain()) { + explain_common::generateServerInfo(result); + } + const auto catalogCache = Grid::get(opCtx)->catalogCache(); auto executionNsRoutingInfoStatus = diff --git a/src/mongo/s/commands/cluster_explain.cpp b/src/mongo/s/commands/cluster_explain.cpp index 5daa2b5dac5..c758fe0cf45 100644 --- a/src/mongo/s/commands/cluster_explain.cpp +++ b/src/mongo/s/commands/cluster_explain.cpp @@ -32,6 +32,7 @@ #include "mongo/bson/bsonmisc.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" @@ -379,6 +380,7 @@ Status ClusterExplain::buildExplainResult(OperationContext* opCtx, buildPlannerInfo(opCtx, shardResults, mongosStageName, out); buildExecStats(shardResults, mongosStageName, millisElapsed, out); + explain_common::generateServerInfo(out); return Status::OK(); } |