From 9d93c7ecb606a8d4260cadf73434b3c2ac1baa01 Mon Sep 17 00:00:00 2001 From: Eric Milkie Date: Mon, 29 Apr 2013 13:34:43 -0400 Subject: SERVER-9417 assert if we stepDown while waiting to satisfy GLE --- jstests/replsets/stepdown3.js | 39 +++++++++++++++++++++++++++++++++++++++ src/mongo/db/repl_block.cpp | 11 +++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 jstests/replsets/stepdown3.js diff --git a/jstests/replsets/stepdown3.js b/jstests/replsets/stepdown3.js new file mode 100644 index 00000000000..ec3261b6637 --- /dev/null +++ b/jstests/replsets/stepdown3.js @@ -0,0 +1,39 @@ +// Test that GLE asserts when the primary steps down while we're waiting for w: + +var replTest = new ReplSetTest({ name: 'testSet', nodes: 2 }); +var nodes = replTest.startSet(); +replTest.initiate(); +var master = replTest.getMaster(); + +// do a write to allow stepping down of the primary; +// otherwise, the primary will refuse to step down +print("\ndo a write"); +master.getDB("test").foo.insert({x:1}); +replTest.awaitReplication(); + +// lock secondary, to pause replication +print("\nlock secondary"); +var locked = replTest.liveNodes.slaves[0]; +printjson( locked.getDB("admin").runCommand({fsync : 1, lock : 1}) ); + +// do a write +print("\ndo a write"); +master.getDB("test").foo.insert({x:2}); + +// step down the primary asyncronously +print("stepdown"); +var command = "sleep(4000); tojson(rs.stepDown());" +var mongoprogram = startMongoProgram( "mongo", "--quiet", "--port", "" + master.port, + "--eval", command ); + +print("getlasterror; should assert"); +var gleFunction = function() { + master.getDB("test").runCommand({getLastError : 1, w: 2 , wtimeout :30000 }) +}; +var result = assert.throws(gleFunction); +print("result of gle:"); +printjson(result); + +// unlock and shut down +printjson(locked.getDB("admin").$cmd.sys.unlock.findOne()); +replTest.stopSet(); diff --git a/src/mongo/db/repl_block.cpp b/src/mongo/db/repl_block.cpp index 37d9321ea16..2bd59d530c3 100644 --- a/src/mongo/db/repl_block.cpp +++ b/src/mongo/db/repl_block.cpp @@ -179,7 +179,9 @@ namespace mongo { } bool waitForReplication(OpTime& op, int w, int maxSecondsToWait) { - massert( 16806, "waitForReplication called but not master anymore", _isMaster() ); + static const int noLongerMasterAssertCode = 16806; + massert(noLongerMasterAssertCode, + "waitForReplication called but not master anymore", _isMaster() ); if ( w <= 1 ) return true; @@ -192,8 +194,13 @@ namespace mongo { scoped_lock mylk(_mutex); while ( ! _replicatedToNum_slaves_locked( op, w ) ) { - if ( ! _threadsWaitingForReplication.timed_wait( mylk.boost() , xt ) ) + if ( ! _threadsWaitingForReplication.timed_wait( mylk.boost() , xt ) ) { + massert(noLongerMasterAssertCode, + "waitForReplication called but not master anymore", _isMaster()); return false; + } + massert(noLongerMasterAssertCode, + "waitForReplication called but not master anymore", _isMaster()); } return true; } -- cgit v1.2.1