diff options
author | Benety Goh <benety@mongodb.com> | 2014-01-08 12:25:27 -0500 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2014-01-12 21:21:49 -0500 |
commit | e0c69afcf27e690ebb518b4a56e05d4d09e06510 (patch) | |
tree | ac409db955d1ff9cdb923e2d448ae14f40d7c556 | |
parent | 2c89a18fd406a673effd10884e9adaf55b68d78d (diff) | |
download | mongo-e0c69afcf27e690ebb518b4a56e05d4d09e06510.tar.gz |
SERVER-5470 enable mongos plan cache commands in pass through mode.
-rw-r--r-- | jstests/plan_cache_commands.js | 2 | ||||
-rw-r--r-- | jstests/slowNightly/sharding_passthrough.js | 1 | ||||
-rw-r--r-- | src/mongo/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/commands/plan_cache_commands.cpp | 3 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_plan_cache_cmd.cpp | 217 |
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 |