diff options
-rw-r--r-- | jstests/replsets/drain.js | 3 | ||||
-rw-r--r-- | jstests/replsets/recovery_mode_read_error.js | 31 | ||||
-rw-r--r-- | src/mongo/db/dbcommands.cpp | 8 |
3 files changed, 41 insertions, 1 deletions
diff --git a/jstests/replsets/drain.js b/jstests/replsets/drain.js index 5d20ff6a9d6..6561bba8ce6 100644 --- a/jstests/replsets/drain.js +++ b/jstests/replsets/drain.js @@ -82,6 +82,9 @@ "find failed with unexpected error code: " + tojson(res)); secondary.slaveOk = false; + // check to make sure reads are not possible during draining + assert.eq('node is in drain mode', res.errmsg); + assert.commandFailedWithCode( secondary.adminCommand({ replSetTest: 1, diff --git a/jstests/replsets/recovery_mode_read_error.js b/jstests/replsets/recovery_mode_read_error.js new file mode 100644 index 00000000000..7958572835c --- /dev/null +++ b/jstests/replsets/recovery_mode_read_error.js @@ -0,0 +1,31 @@ + +/* + This test checks to make sure nodes that are in RECOVERING mode + cannot accept reads and throw the correct errors. + - use replSetMaintenance to send secondary into recovering mode + - run a find() on secondary to make sure it throws the "node is + recovering" error message + +*/ + +(function() { + "use strict"; + var replTest = new ReplSetTest({name: 'recovery_mode_read_error', nodes: 2}); + var conns = replTest.startSet(); + + replTest.initiate(); + + // Make sure we have a master + var primary = replTest.getPrimary(); + primary.getDB("bar").foo.insert({foo: 3}); + + var secondary = replTest.getSecondary(); + + print("secondary going into maintenance mode (recovery mode)"); + assert.commandWorked(secondary.adminCommand({replSetMaintenance: 1})); + + var recv = secondary.getDB("bar").runCommand({find: "foo"}); + assert.commandFailed(recv); + assert.eq(recv.errmsg, "node is recovering"); + +})(); diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index ae0830753c6..6e5cfb2d849 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -1329,10 +1329,16 @@ void Command::execCommand(OperationContext* txn, replCoord->getReplicationMode() == repl::ReplicationCoordinator::modeReplSet && !replCoord->canAcceptWritesForDatabase(dbname) && !replCoord->getMemberState().secondary()) { - uasserted(ErrorCodes::NotMasterOrSecondary, "node is recovering"); + + if (replCoord->getMemberState().recovering()) { + uasserted(ErrorCodes::NotMasterOrSecondary, "node is recovering"); + } + invariant(replCoord->getMemberState().primary()); + uasserted(ErrorCodes::NotMasterOrSecondary, "node is in drain mode"); } } + if (command->adminOnly()) { LOG(2) << "command: " << request.getCommandName(); } |