summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Percy <david.percy@mongodb.com>2019-11-13 22:26:52 +0000
committerevergreen <evergreen@mongodb.com>2019-11-13 22:26:52 +0000
commite75d261790ca1fdbe21afce043af16b552d9a293 (patch)
treeb4558fbfbb694f311522881832c9723b45ca2474
parent3ffd21eb0555cf729daf6f5ee9281137058ac9b8 (diff)
downloadmongo-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.yml2
-rw-r--r--jstests/aggregation/explain.js14
-rw-r--r--jstests/sharding/explain_cmd.js2
-rw-r--r--src/mongo/db/query/SConscript1
-rw-r--r--src/mongo/db/query/explain.cpp16
-rw-r--r--src/mongo/db/query/explain.h8
-rw-r--r--src/mongo/db/query/explain_common.cpp52
-rw-r--r--src/mongo/db/query/explain_common.h49
-rw-r--r--src/mongo/s/commands/cluster_aggregate.cpp5
-rw-r--r--src/mongo/s/commands/cluster_explain.cpp2
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();
}