summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2014-01-08 12:25:27 -0500
committerBenety Goh <benety@mongodb.com>2014-01-12 21:21:49 -0500
commite0c69afcf27e690ebb518b4a56e05d4d09e06510 (patch)
treeac409db955d1ff9cdb923e2d448ae14f40d7c556
parent2c89a18fd406a673effd10884e9adaf55b68d78d (diff)
downloadmongo-e0c69afcf27e690ebb518b4a56e05d4d09e06510.tar.gz
SERVER-5470 enable mongos plan cache commands in pass through mode.
-rw-r--r--jstests/plan_cache_commands.js2
-rw-r--r--jstests/slowNightly/sharding_passthrough.js1
-rw-r--r--src/mongo/SConscript1
-rw-r--r--src/mongo/db/commands/plan_cache_commands.cpp3
-rw-r--r--src/mongo/s/commands/cluster_plan_cache_cmd.cpp217
5 files changed, 221 insertions, 3 deletions
diff --git a/jstests/plan_cache_commands.js b/jstests/plan_cache_commands.js
index 91bf1c187a1..53dc2e4d690 100644
--- a/jstests/plan_cache_commands.js
+++ b/jstests/plan_cache_commands.js
@@ -24,7 +24,7 @@
* query.
*/
-var t = db.jstests_query_cache;
+var t = db.jstests_plan_cache_commands;
t.drop();
diff --git a/jstests/slowNightly/sharding_passthrough.js b/jstests/slowNightly/sharding_passthrough.js
index 70e007c88a6..6df02939ea8 100644
--- a/jstests/slowNightly/sharding_passthrough.js
+++ b/jstests/slowNightly/sharding_passthrough.js
@@ -113,7 +113,6 @@ files.forEach(function(x) {
'bench_test.*|' +
'mr_replaceIntoDB|' +
'mr_auth|' +
- 'plan_cache_commands|' +
'queryoptimizera|' +
'indexStatsCommand|' +
'reversecursor|' +
diff --git a/src/mongo/SConscript b/src/mongo/SConscript
index 71beeaea051..758e1884c41 100644
--- a/src/mongo/SConscript
+++ b/src/mongo/SConscript
@@ -696,6 +696,7 @@ mongosLibraryFiles = [
"s/commands_public.cpp",
"s/commands/auth_schema_upgrade_s.cpp",
"s/commands/cluster_merge_chunks_cmd.cpp",
+ "s/commands/cluster_plan_cache_cmd.cpp",
"s/commands/cluster_write_cmd.cpp",
"s/request.cpp",
"s/client_info.cpp",
diff --git a/src/mongo/db/commands/plan_cache_commands.cpp b/src/mongo/db/commands/plan_cache_commands.cpp
index e8f4b71257f..bcf37f9561a 100644
--- a/src/mongo/db/commands/plan_cache_commands.cpp
+++ b/src/mongo/db/commands/plan_cache_commands.cpp
@@ -218,7 +218,8 @@ namespace mongo {
}
PlanCacheGenerateKey::PlanCacheGenerateKey() : PlanCacheCommand("planCacheGenerateKey",
- "Returns a key into the cache for a query. Similar queries with the same query shape "
+ "Returns a key into the cache for a query. "
+ "Similar queries with the same query shape "
"will resolve to the same key.",
ActionType::planCacheRead) { }
diff --git a/src/mongo/s/commands/cluster_plan_cache_cmd.cpp b/src/mongo/s/commands/cluster_plan_cache_cmd.cpp
new file mode 100644
index 00000000000..35802c9f50a
--- /dev/null
+++ b/src/mongo/s/commands/cluster_plan_cache_cmd.cpp
@@ -0,0 +1,217 @@
+/**
+ * Copyright (C) 2014 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * 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 GNU Affero General 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/base/init.h"
+#include "mongo/base/error_codes.h"
+#include "mongo/db/auth/authorization_session.h"
+#include "mongo/db/client_basic.h"
+#include "mongo/db/commands.h"
+#include "mongo/s/client_info.h"
+#include "mongo/s/config.h"
+#include "mongo/s/grid.h"
+#include "mongo/s/stale_exception.h"
+#include "mongo/s/strategy.h"
+
+namespace mongo {
+
+ using std::string;
+ using std::vector;
+
+ /**
+ * Base class for mongos plan cache commands.
+ * Cluster plan cache commands don't do much more than
+ * forwarding the commands to all shards and combining the results.
+ */
+ class ClusterPlanCacheCmd : public Command {
+ MONGO_DISALLOW_COPYING(ClusterPlanCacheCmd);
+ public:
+
+ virtual ~ClusterPlanCacheCmd() {
+ }
+
+ bool logTheOp() {
+ return false;
+ }
+
+ bool slaveOk() const {
+ return false;
+ }
+
+ LockType locktype() const {
+ return Command::NONE;
+ }
+
+ Status checkAuthForCommand( ClientBasic* client,
+ const std::string& dbname,
+ const BSONObj& cmdObj ) {
+ AuthorizationSession* authzSession = client->getAuthorizationSession();
+ ResourcePattern pattern = parseResourcePattern(dbname, cmdObj);
+
+ if (authzSession->isAuthorizedForActionsOnResource(pattern, _actionType)) {
+ return Status::OK();
+ }
+
+ return Status(ErrorCodes::Unauthorized, "unauthorized");
+ }
+
+ // Cluster plan cache command entry point.
+ bool run( const std::string& dbname,
+ BSONObj& cmdObj,
+ int options,
+ std::string& errmsg,
+ BSONObjBuilder& result,
+ bool fromRepl );
+
+ public:
+
+ /**
+ * Instantiates a command that can be invoked by "name", which will be described by
+ * "helpText", and will require privilege "actionType" to run.
+ */
+ ClusterPlanCacheCmd( const std::string& name, const std::string& helpText,
+ ActionType actionType ) :
+ Command( name ), _helpText( helpText ), _actionType( actionType ) {
+ }
+
+ private:
+
+ std::string _helpText;
+ ActionType _actionType;
+ };
+
+ //
+ // Cluster plan cache command implementation(s) below
+ //
+
+ bool ClusterPlanCacheCmd::run( const std::string& dbName,
+ BSONObj& cmdObj,
+ int options,
+ std::string& errMsg,
+ BSONObjBuilder& result,
+ bool ) {
+ const std::string fullns = parseNs(dbName, cmdObj);
+ NamespaceString nss(fullns);
+
+ // Dispatch command to all the shards.
+ // Targeted shard commands are generally data-dependent but plan cache
+ // commands are tied to query shape (data has no effect on query shape).
+ vector<Strategy::CommandResult> results;
+ STRATEGY->commandOp(dbName, cmdObj, options, nss.ns(), BSONObj(), &results);
+
+ // Set value of first shard result's "ok" field.
+ bool clusterCmdResult = true;
+
+ for (vector<Strategy::CommandResult>::const_iterator i = results.begin();
+ i != results.end(); ++i) {
+ const Strategy::CommandResult& cmdResult = *i;
+
+ // XXX: In absence of sensible aggregation strategy,
+ // promote first shard's result to top level.
+ if (i == results.begin()) {
+ result.appendElements(cmdResult.result);
+ clusterCmdResult = cmdResult.result["ok"].trueValue();
+ }
+
+ // Append shard result as a sub object.
+ // Name the field after the shard.
+ string shardName = cmdResult.shardTarget.getName();
+ result.append(shardName, cmdResult.result);
+ }
+
+ return clusterCmdResult;
+ }
+
+ //
+ // Register plan cache commands at startup
+ //
+
+ namespace {
+
+ MONGO_INITIALIZER(RegisterPlanCacheCommands)(InitializerContext* context) {
+ // Leaked intentionally: a Command registers itself when constructed.
+
+ new ClusterPlanCacheCmd(
+ "planCacheListKeys",
+ "Displays keys of all cached queries in a collection.",
+ ActionType::planCacheRead );
+
+ new ClusterPlanCacheCmd(
+ "planCacheClear",
+ "Drops all cached queries in a collection.",
+ ActionType::planCacheWrite );
+
+ new ClusterPlanCacheCmd(
+ "planCacheGenerateKey",
+ "Returns a key into the cache for a query. "
+ "Similar queries with the same query shape "
+ "will resolve to the same key.",
+ ActionType::planCacheRead );
+
+ new ClusterPlanCacheCmd(
+ "planCacheGet",
+ "Looks up the query shape, sort order and projection using a cache key.",
+ ActionType::planCacheRead );
+
+ new ClusterPlanCacheCmd(
+ "planCacheDrop",
+ "Drops using a cache key.",
+ ActionType::planCacheWrite );
+
+ new ClusterPlanCacheCmd(
+ "planCacheListPlans",
+ "Displays the cached plans for a query shape.",
+ ActionType::planCacheRead );
+
+ new ClusterPlanCacheCmd(
+ "planCachePinPlan",
+ "This command allows the user to pin a plan so that "
+ "it will always be used for query execution.",
+ ActionType::planCacheWrite );
+
+ new ClusterPlanCacheCmd(
+ "planCacheUnpinPlan",
+ "This command allows the user to unpin any plan that might be pinned to a query.",
+ ActionType::planCacheWrite );
+
+ new ClusterPlanCacheCmd(
+ "planCacheAddPlan",
+ "Adds a user-defined plan to an existing query in the cache.",
+ ActionType::planCacheWrite );
+
+ new ClusterPlanCacheCmd(
+ "planCacheShunPlan",
+ "Marks a plan as non-executable. This takes the plan out of consideration "
+ "in the plan selection for query execution.",
+ ActionType::planCacheWrite );
+
+ return Status::OK();
+ }
+
+ } // namespace
+
+} // namespace mongo