diff options
author | David Storch <david.storch@10gen.com> | 2014-09-25 12:35:38 -0400 |
---|---|---|
committer | David Storch <david.storch@10gen.com> | 2014-09-25 18:08:57 -0400 |
commit | 77b00970997d13d0758c745e5a94fc79982d4401 (patch) | |
tree | 2eba1844a398aa2188755553cbfec4f3a1f86d49 | |
parent | f12b81dd15143d62768a4082f11ccc26692d6625 (diff) | |
download | mongo-77b00970997d13d0758c745e5a94fc79982d4401.tar.gz |
SERVER-15233 allow plan cache commands to run on secondaries is slaveOk explicitly set to true
-rw-r--r-- | jstests/replsets/plan_cache_slaveok.js | 68 | ||||
-rw-r--r-- | src/mongo/db/commands/plan_cache_commands.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/commands/plan_cache_commands.h | 2 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_plan_cache_cmd.cpp | 8 |
4 files changed, 80 insertions, 2 deletions
diff --git a/jstests/replsets/plan_cache_slaveok.js b/jstests/replsets/plan_cache_slaveok.js new file mode 100644 index 00000000000..65d2d36cd18 --- /dev/null +++ b/jstests/replsets/plan_cache_slaveok.js @@ -0,0 +1,68 @@ +// Verify that the plan cache commands can be run on secondaries, but only +// if slave ok is explicitly set. + +var name = "plan_cache_slaveok"; + +function assertPlanCacheCommandsSucceed(db) { + // .listQueryShapes() + assert.commandWorked(db.runCommand({ + planCacheListQueryShapes: name + })); + + // .getPlansByQuery() + assert.commandWorked(db.runCommand({ + planCacheListPlans: name, + query: {a: 1} + })); + + // .clear() + assert.commandWorked(db.runCommand({ + planCacheClear: name, + query: {a: 1} + })); +} + +function assertPlanCacheCommandsFail(db) { + // .listQueryShapes() + assert.commandFailed(db.runCommand({ + planCacheListQueryShapes: name + })); + + // .getPlansByQuery() + assert.commandFailed(db.runCommand({ + planCacheListPlans: name, + query: {a: 1} + })); + + // .clear() + assert.commandFailed(db.runCommand({ + planCacheClear: name, + query: {a: 1} + })); +} + +print("Start replica set with two nodes"); +var replTest = new ReplSetTest({name: name, nodes: 2}); +var nodes = replTest.startSet(); +replTest.initiate(); +var primary = replTest.getMaster(); + +// Insert a document and let it sync to the secondary. +print("Initial sync"); +primary.getDB("test")[name].insert({a: 1}); +replTest.awaitReplication(); + +// Check that the document is present on the primary. +assert.eq(1, primary.getDB("test")[name].findOne({a: 1})["a"]); + +// Make sure the plan cache commands succeed on the primary. +assertPlanCacheCommandsSucceed(primary.getDB("test")); + +// With slave ok false, the commands should fail on the secondary. +var secondary = replTest.getSecondary(); +secondary.getDB("test").getMongo().setSlaveOk(false); +assertPlanCacheCommandsFail(secondary.getDB("test")); + +// With slave ok true, the commands should succeed on the secondary. +secondary.getDB("test").getMongo().setSlaveOk(true); +assertPlanCacheCommandsSucceed(secondary.getDB("test")); diff --git a/src/mongo/db/commands/plan_cache_commands.cpp b/src/mongo/db/commands/plan_cache_commands.cpp index 6ca998a1b71..601e9b47318 100644 --- a/src/mongo/db/commands/plan_cache_commands.cpp +++ b/src/mongo/db/commands/plan_cache_commands.cpp @@ -141,6 +141,10 @@ namespace mongo { return false; } + bool PlanCacheCommand::slaveOverrideOk() const { + return true; + } + void PlanCacheCommand::help(stringstream& ss) const { ss << helpText; } diff --git a/src/mongo/db/commands/plan_cache_commands.h b/src/mongo/db/commands/plan_cache_commands.h index 1a4a49a3c4f..34660d9a48b 100644 --- a/src/mongo/db/commands/plan_cache_commands.h +++ b/src/mongo/db/commands/plan_cache_commands.h @@ -65,6 +65,8 @@ namespace mongo { virtual bool slaveOk() const; + virtual bool slaveOverrideOk() const; + virtual void help(std::stringstream& ss) const; /** diff --git a/src/mongo/s/commands/cluster_plan_cache_cmd.cpp b/src/mongo/s/commands/cluster_plan_cache_cmd.cpp index 1aa015a495b..5bd87f4eb8a 100644 --- a/src/mongo/s/commands/cluster_plan_cache_cmd.cpp +++ b/src/mongo/s/commands/cluster_plan_cache_cmd.cpp @@ -58,6 +58,10 @@ namespace mongo { return false; } + bool slaveOverrideOk() const { + return true; + } + virtual bool isWriteCommandForConfigServer() const { return false; } void help(stringstream& ss) const { @@ -69,11 +73,11 @@ namespace mongo { 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"); } |