diff options
author | Antonin Kral <a.kral@bobek.cz> | 2011-09-14 17:08:06 +0200 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2011-09-14 17:08:06 +0200 |
commit | 5d342a758c6095b4d30aba0750b54f13b8916f51 (patch) | |
tree | 762e9aa84781f5e3b96db2c02d356c29cf0217c0 /jstests/replsets | |
parent | cbe2d992e9cd1ea66af9fa91df006106775d3073 (diff) | |
download | mongodb-5d342a758c6095b4d30aba0750b54f13b8916f51.tar.gz |
Imported Upstream version 2.0.0
Diffstat (limited to 'jstests/replsets')
37 files changed, 1660 insertions, 704 deletions
diff --git a/jstests/replsets/auth1.js b/jstests/replsets/auth1.js index 60e4b95..71ab2d9 100644 --- a/jstests/replsets/auth1.js +++ b/jstests/replsets/auth1.js @@ -3,17 +3,27 @@ load("jstests/replsets/rslib.js"); var name = "rs_auth1"; -var port = allocatePorts(4); -var path = "jstests/replsets/"; +var port = allocatePorts(5); +var path = "jstests/libs/"; + + +print("try starting mongod with auth"); +var m = runMongoProgram( "mongod", "--auth", "--port", port[4], "--dbpath", "/data/db/wrong-auth"); + +assert.throws(function() { + m.getDB("local").auth("__system", ""); +}); + +stopMongod(port[4]); + - print("reset permissions"); run("chmod", "644", path+"key1"); run("chmod", "644", path+"key2"); print("try starting mongod"); -var m = runMongoProgram( "mongod", "--keyFile", path+"key1", "--port", port[0], "--dbpath", "/data/db/" + name); +m = runMongoProgram( "mongod", "--keyFile", path+"key1", "--port", port[0], "--dbpath", "/data/db/" + name); print("should fail with wrong permissions"); @@ -81,6 +91,10 @@ function doQueryOn(p) { doQueryOn(slave); master.adminCommand({logout:1}); + +print("unauthorized:"); +printjson(master.adminCommand({replSetGetStatus : 1})); + doQueryOn(master); @@ -125,11 +139,12 @@ master.auth("bar", "baz"); for (var i=0; i<1000; i++) { master.foo.insert({x:i, foo : "bar"}); } -master.runCommand({getlasterror:1, w:3, wtimeout:60000}); +var result = master.runCommand({getlasterror:1, w:2, wtimeout:60000}); +printjson(result); print("resync"); -rs.restart(0); +rs.restart(0, {"keyFile" : path+"key1"}); print("add some more data 2"); @@ -159,7 +174,7 @@ master.getSisterDB("admin").auth("foo", "bar"); print("shouldn't ever sync"); -for (var i = 0; i<30; i++) { +for (var i = 0; i<10; i++) { print("iteration: " +i); var results = master.adminCommand({replSetGetStatus:1}); printjson(results); @@ -177,9 +192,15 @@ conn = new MongodRunner(port[3], "/data/db/"+name+"-3", null, null, ["--replSet" conn.start(); wait(function() { + try { var results = master.adminCommand({replSetGetStatus:1}); printjson(results); return results.members[3].state == 2; + } + catch (e) { + print(e); + } + return false; }); print("make sure it has the config, too"); diff --git a/jstests/replsets/cloneDb.js b/jstests/replsets/cloneDb.js index 6d2d0f3..2519c09 100644 --- a/jstests/replsets/cloneDb.js +++ b/jstests/replsets/cloneDb.js @@ -6,34 +6,36 @@ doTest = function( signal ) { var N = 2000 - // ~1KB string + print("~1KB string"); var Text = '' for (var i = 0; i < 40; i++) Text += 'abcdefghijklmnopqrstuvwxyz' - // Create replica set + print("Create replica set"); var repset = new ReplicaSet ('testSet', 3) .begin() var master = repset.getMaster() var db1 = master.getDB('test') - // Insert data + print("Insert data"); for (var i = 0; i < N; i++) { db1['foo'].insert({x: i, text: Text}) db1.getLastError(2) // wait to be copied to at least one secondary } - // Create single server + print("Create single server"); var solo = new Server ('singleTarget') var soloConn = solo.begin() + soloConn.getDB("admin").runCommand({setParameter:1,logLevel:5}); + var db2 = soloConn.getDB('test') - // Clone db from replica set to single server + print("Clone db from replica set to single server"); db2.cloneDatabase (repset.getURL()) - // Confirm clone worked + print("Confirm clone worked"); assert.eq (Text, db2['foo'] .findOne({x: N-1}) ['text'], 'cloneDatabase failed (test1)') - // Now test the reverse direction + print("Now test the reverse direction"); db1 = master.getDB('test2') db2 = soloConn.getDB('test2') for (var i = 0; i < N; i++) { @@ -43,7 +45,7 @@ doTest = function( signal ) { db1.cloneDatabase (solo.host()) assert.eq (Text, db2['foo'] .findOne({x: N-1}) ['text'], 'cloneDatabase failed (test2)') - // Shut down replica set and single server + print("Shut down replica set and single server"); solo.end() repset.stopSet( signal ) } diff --git a/jstests/replsets/config1.js b/jstests/replsets/config1.js deleted file mode 100644 index 748ce8f..0000000 --- a/jstests/replsets/config1.js +++ /dev/null @@ -1,21 +0,0 @@ -doTest = function( signal ) { - var name = 'config1'; - - var replTest = new ReplSetTest( {name: name, nodes: 3} ); - var nodes = replTest.startSet(); - - var config = replTest.getReplSetConfig(); - config.settings = {"heartbeatSleep" : .5, heartbeatTimeout : .8}; - - replTest.initiate(config); - - // Call getMaster to return a reference to the node that's been - // elected master. - var master = replTest.getMaster(); - - config = master.getDB("local").system.replset.findOne(); - assert.eq(config.settings.heartbeatSleep, .5); - assert.eq(config.settings.heartbeatTimeout, .8); -}; - -doTest(15); diff --git a/jstests/replsets/downstream.js b/jstests/replsets/downstream.js new file mode 100755 index 0000000..795e667 --- /dev/null +++ b/jstests/replsets/downstream.js @@ -0,0 +1,36 @@ +// BUG: [SERVER-1768] replica set getlasterror {w: 2} after 2000 +// inserts hangs while secondary servers log "replSet error RS102 too stale to catch up" every once in a while + +function newReplicaSet (name, numServers) { + var rs = new ReplSetTest({name: name, nodes: numServers}) + rs.startSet() + rs.initiate() + rs.awaitReplication() + return rs +} + +function go() { +var N = 2000 + +// ~1KB string +var Text = '' +for (var i = 0; i < 40; i++) + Text += 'abcdefghijklmnopqrstuvwxyz' + +// Create replica set of 3 servers +var repset = newReplicaSet('repset', 3) +var conn = repset.getMaster() +var db = conn.getDB('test') + +// Add data to it +for (var i = 0; i < N; i++) + db['foo'].insert({x: i, text: Text}) + +// wait to be copied to at least one secondary (BUG hangs here) +db.getLastError(2) + +print('getlasterror_w2.js SUCCESS') +} + +// turn off until fixed +//go(); diff --git a/jstests/replsets/fastsync.js b/jstests/replsets/fastsync.js index d7c3905..1c9c215 100644 --- a/jstests/replsets/fastsync.js +++ b/jstests/replsets/fastsync.js @@ -22,7 +22,7 @@ var wait = function(f) { } var reconnect = function(a) { - wait(function() { + wait(function() { try { a.getDB("foo").bar.stats(); return true; @@ -33,7 +33,7 @@ var reconnect = function(a) { }); }; -ports = allocatePorts( 3 ); +ports = allocatePorts( 4 ); var basename = "jstests_fastsync"; var basePath = "/data/db/" + basename; @@ -48,7 +48,7 @@ var admin = p.getDB("admin"); var foo = p.getDB("foo"); var local = p.getDB("local"); -var config = {_id : basename, members : [{_id : 0, host : hostname+":"+ports[0]}]}; +var config = {_id : basename, members : [{_id : 0, host : hostname+":"+ports[0], priority:2}]}; printjson(config); var result = admin.runCommand({replSetInitiate : config}); print("result:"); @@ -59,10 +59,19 @@ while (count < 10 && result.ok != 1) { count++; sleep(2000); result = admin.runCommand({replSetInitiate : config}); -} +} assert(result.ok, tojson(result)); -assert.soon(function() { return admin.runCommand({isMaster:1}).ismaster; }); +assert.soon(function() { result = false; + try { + result = admin.runCommand({isMaster:1}).ismaster; + } + catch(e) { + print(e); + return false; + } + return result; + }); print("1"); for (var i=0; i<100000; i++) { @@ -73,45 +82,113 @@ print("total in foo: "+foo.bar.count()); print("2"); admin.runCommand( {fsync:1,lock:1} ); -copyDbpath( basePath + "-p", basePath + "-s" ); +copyDbpath( basePath + "-p", basePath + "-s"+1 ); admin.$cmd.sys.unlock.findOne(); - print("3"); -var sargs = new MongodRunner( ports[ 1 ], basePath + "-s", false, false, +var startSlave = function(n) { + var sargs = new MongodRunner( ports[ n ], basePath + "-s"+n, false, false, ["--replSet", basename, "--fastsync", "--oplogSize", 2], {no_bind : true} ); -var reuseData = true; -sargs.start(reuseData); + var reuseData = true; + var conn = sargs.start(reuseData); + + config = local.system.replset.findOne(); + config.version++; + config.members.push({_id:n, host:hostname+":"+ports[n]}); + + result = admin.runCommand({replSetReconfig : config}); + printjson(result); + assert(result.ok, "reconfig worked"); + reconnect(p); + + print("4"); + var status = admin.runCommand({replSetGetStatus : 1}); + var count = 0; + while (status.members[n].state != 2 && count < 200) { + print("not a secondary yet"); + if (count % 10 == 0) { + printjson(status); + } + assert(!status.members[n].errmsg || !status.members[n].errmsg.match("^initial sync cloning db")); -config = local.system.replset.findOne(); -config.version++; -config.members.push({_id:1, host:hostname+":"+ports[1]}); + sleep(1000); -result = admin.runCommand({replSetReconfig : config}); -assert(result.ok, "reconfig worked"); -reconnect(p); + // disconnection could happen here + try { + status = admin.runCommand({replSetGetStatus : 1}); + } + catch (e) { + print(e); + } + count++; + } -print("4"); -var status = admin.runCommand({replSetGetStatus : 1}); -var count = 0; -while (status.members[1].state != 2 && count < 200) { - print("not a secondary yet"); - if (count % 10 == 0) { - printjson(status); - } - assert(!status.members[1].errmsg || !status.members[1].errmsg.match("^initial sync cloning db")); - - sleep(1000); - - // disconnection could happen here - try { - status = admin.runCommand({replSetGetStatus : 1}); - } - catch (e) { - print(e); - } - count++; + assert.eq(status.members[n].state, 2); + + assert.soon(function() { + return admin.runCommand({isMaster : 1}).ismaster; + }); + + admin.foo.insert({x:1}); + assert.soon(function() { + var last = local.oplog.rs.find().sort({$natural:-1}).limit(1).next(); + var cur = conn.getDB("local").oplog.rs.find().sort({$natural:-1}).limit(1).next(); + print("last: "+tojson(last)+" cur: "+tojson(cur)); + return cur != null && last != null && cur.ts.t == last.ts.t && cur.ts.i == last.ts.i; + }); + + return conn; +}; + +var s1 = startSlave(1); + +var me1 = s1.getDB("local").me.findOne(); + +print("me: " +me1._id); +assert(me1._id != null); + +print("5"); +s1.getDB("admin").runCommand( {fsync:1,lock:1} ); +copyDbpath( basePath + "-s1", basePath + "-s2" ); +s1.getDB("admin").$cmd.sys.unlock.findOne(); + +var s2 = startSlave(2); + +var me2 = s2.getDB("local").me.findOne(); + +print("me: " +me2._id); +assert(me1._id != me2._id); + +print("restart member with a different port and make it a new set"); +try { + p.getDB("admin").runCommand({shutdown:1}); +} +catch(e) { + print("good, shutting down: " +e); } +sleep(10000); + +pargs = new MongodRunner( ports[ 3 ], basePath + "-p", false, false, + ["--replSet", basename, "--oplogSize", 2], + {no_bind : true} ); +p = pargs.start(true); + +printjson(p.getDB("admin").runCommand({replSetGetStatus:1})); + +p.getDB("admin").runCommand({replSetReconfig : { + _id : basename, + members : [{_id:0, host : hostname+":"+ports[3]}] + }, force : true}); + +print("start waiting for primary..."); +assert.soon(function() { + try { + return p.getDB("admin").runCommand({isMaster : 1}).ismaster; + } + catch(e) { + print(e); + } + return false; + }, "waiting for master", 60000); -assert.eq(status.members[1].state, 2); diff --git a/jstests/replsets/initial_sync1.js b/jstests/replsets/initial_sync1.js index df978c4..4cfd606 100644 --- a/jstests/replsets/initial_sync1.js +++ b/jstests/replsets/initial_sync1.js @@ -95,12 +95,11 @@ replTest.stop(1); print("8. Eventually it should become a secondary"); print("if initial sync has started, this will cause it to fail and sleep for 5 minutes"); -sleep(5*60*1000); wait(function() { var status = admin_s2.runCommand({replSetGetStatus:1}); occasionally(function() { printjson(status); }); return status.members[2].state == 2; - }); + }, 350); print("9. Bring #2 back up"); @@ -122,5 +121,5 @@ for (var i=0; i<10000; i++) { print("11. Everyone happy eventually"); -replTest.awaitReplication(); +replTest.awaitReplication(300000); diff --git a/jstests/replsets/initial_sync3.js b/jstests/replsets/initial_sync3.js index 471aa16..7f2af94 100644 --- a/jstests/replsets/initial_sync3.js +++ b/jstests/replsets/initial_sync3.js @@ -43,14 +43,14 @@ wait(function() { if (!status.members) { return false; } - + for (i=0; i<7; i++) { if (status.members[i].state != 1 && status.members[i].state != 2) { return false; } } return true; - + }); replTest.awaitReplication(); @@ -66,6 +66,7 @@ rs2.initiate(); master = rs2.getMaster(); var config = master.getDB("local").system.replset.findOne(); config.version++; +config.members[0].priority = 2; config.members[0].initialSync = {state : 2}; config.members[1].initialSync = {state : 1}; try { @@ -75,12 +76,34 @@ catch(e) { print("trying to reconfigure: "+e); } -master = rs2.getMaster(); -config = master.getDB("local").system.replset.findOne(); +// wait for a heartbeat, too, just in case sync happens before hb +assert.soon(function() { + try { + for (var n in rs2.nodes) { + if (rs2.nodes[n].getDB("local").system.replset.findOne().version != 2) { + return false; + } + } + } + catch (e) { + return false; + } + return true; +}); + +rs2.awaitReplication(); + +// test partitioning +master = rs2.bridge(); +rs2.partition(0, 2); + +master.getDB("foo").bar.baz.insert({x:1}); +rs2.awaitReplication(); -assert(typeof(config.members[0].initialSync) == "object"); -assert.eq(config.members[0].initialSync.state, 2); -assert.eq(config.members[1].initialSync.state, 1); +master.getDB("foo").bar.baz.insert({x:2}); +var x = master.getDB("foo").runCommand({getLastError : 1, w : 3, wtimeout : 5000}); +printjson(x); +assert.eq(null, x.err); rs2.stopSet(); diff --git a/jstests/replsets/key1 b/jstests/replsets/key1 deleted file mode 100644 index b5c19e4..0000000 --- a/jstests/replsets/key1 +++ /dev/null @@ -1 +0,0 @@ -foop de doop diff --git a/jstests/replsets/key2 b/jstests/replsets/key2 deleted file mode 100644 index cbde821..0000000 --- a/jstests/replsets/key2 +++ /dev/null @@ -1 +0,0 @@ -other key diff --git a/jstests/replsets/maintenance.js b/jstests/replsets/maintenance.js new file mode 100644 index 0000000..5b068cd --- /dev/null +++ b/jstests/replsets/maintenance.js @@ -0,0 +1,32 @@ + + +var replTest = new ReplSetTest( {name: 'unicomplex', nodes: 3} ); +var conns = replTest.startSet(); +replTest.initiate(); + +// Make sure we have a master +var master = replTest.getMaster(); + +for (i=0;i<10000; i++) { master.getDB("bar").foo.insert({x:1,y:i,abc:123,str:"foo bar baz"}); } +for (i=0;i<1000; i++) { master.getDB("bar").foo.update({y:i},{$push :{foo : "barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr"}}); } + +replTest.awaitReplication(); + +assert.soon(function() { return conns[2].getDB("admin").isMaster().secondary; }); + +join = startParallelShell( "db.getSisterDB('bar').runCommand({compact : 'foo'});", replTest.ports[2] ); + +print("check secondary goes to recovering"); +assert.soon(function() { return !conns[2].getDB("admin").isMaster().secondary; }); + +print("joining"); +join(); + +print("check secondary becomes a secondary again"); +var x = 0; +assert.soon(function() { + var im = conns[2].getDB("admin").isMaster(); + if (x++ % 5 == 0) printjson(im); + return im.secondary; +}); + diff --git a/jstests/replsets/majority.js b/jstests/replsets/majority.js new file mode 100644 index 0000000..6df1a41 --- /dev/null +++ b/jstests/replsets/majority.js @@ -0,0 +1,60 @@ +var num = 5; +var host = getHostName(); +var name = "tags"; +var timeout = 10000; + +var replTest = new ReplSetTest( {name: name, nodes: num, startPort:31000} ); +var nodes = replTest.startSet(); +var port = replTest.ports; +replTest.initiate({_id : name, members : + [ + {_id:0, host : host+":"+port[0], priority : 2}, + {_id:1, host : host+":"+port[1]}, + {_id:2, host : host+":"+port[2]}, + {_id:3, host : host+":"+port[3], arbiterOnly : true}, + {_id:4, host : host+":"+port[4], arbiterOnly : true}, + ], + }); + +replTest.awaitReplication(); +replTest.bridge(); + +var testInsert = function() { + master.getDB("foo").bar.insert({x:1}); + var result = master.getDB("foo").runCommand({getLastError:1, w:"majority", wtimeout:timeout}); + printjson(result); + return result; +}; + +var master = replTest.getMaster(); + +print("get back in the groove"); +testInsert(); +replTest.awaitReplication(); + +print("makes sure majority works"); +assert.eq(testInsert().err, null); + +print("setup: 0,1 | 2,3,4"); +replTest.partition(0,2); +replTest.partition(0,3); +replTest.partition(0,4); +replTest.partition(1,2); +replTest.partition(1,3); +replTest.partition(1,4); + +print("make sure majority doesn't work"); +// primary should now be 2 +master = replTest.getMaster(); +assert.eq(testInsert().err, "timeout"); + +print("bring set back together"); +replTest.unPartition(0,2); +replTest.unPartition(0,3); +replTest.unPartition(1,4); + +master = replTest.getMaster(); + +print("make sure majority works"); +assert.eq(testInsert().err, null); + diff --git a/jstests/replsets/randomcommands1.js b/jstests/replsets/randomcommands1.js deleted file mode 100644 index c451e74..0000000 --- a/jstests/replsets/randomcommands1.js +++ /dev/null @@ -1,29 +0,0 @@ - -replTest = new ReplSetTest( {name: 'randomcommands1', nodes: 3} ); - -nodes = replTest.startSet(); -replTest.initiate(); - -master = replTest.getMaster(); -slaves = replTest.liveNodes.slaves; -printjson(replTest.liveNodes); - -db = master.getDB("foo") -t = db.foo - -ts = slaves.map( function(z){ z.setSlaveOk(); return z.getDB( "foo" ).foo; } ) - -t.save({a: 1000}); -t.ensureIndex( { a : 1 } ) - -db.getLastError( 3 , 30000 ) - -ts.forEach( function(z){ assert.eq( 2 , z.getIndexKeys().length , "A " + z.getMongo() ); } ) - -t.reIndex() - -db.getLastError( 3 , 30000 ) -ts.forEach( function(z){ assert.eq( 2 , z.getIndexKeys().length , "A " + z.getMongo() ); } ) - -replTest.stopSet( 15 ) - diff --git a/jstests/replsets/reconfig.js b/jstests/replsets/reconfig.js new file mode 100644 index 0000000..b7dca03 --- /dev/null +++ b/jstests/replsets/reconfig.js @@ -0,0 +1,69 @@ + +// try reconfiguring with servers down + +var replTest = new ReplSetTest({ name: 'testSet', nodes: 5 }); +var nodes = replTest.startSet(); +replTest.initiate(); + +var master = replTest.getMaster(); + +print("initial sync"); +master.getDB("foo").bar.insert({X:1}); +replTest.awaitReplication(); + +print("stopping 3 & 4"); +replTest.stop(3); +replTest.stop(4); + +print("reconfiguring"); +master = replTest.getMaster(); +var config = master.getDB("local").system.replset.findOne(); +var oldVersion = config.version++; +config.members[0].votes = 2; +config.members[3].votes = 2; +try { + master.getDB("admin").runCommand({replSetReconfig : config}); +} +catch(e) { + print(e); +} + +var config = master.getDB("local").system.replset.findOne(); +assert.eq(oldVersion+1, config.version); + + +print("0 & 3 up; 1, 2, 4 down"); +replTest.restart(3); + +// in case 0 isn't master +replTest.awaitReplication(); + +replTest.stop(1); +replTest.stop(2); + +print("try to reconfigure with a 'majority' down"); +oldVersion = config.version; +config.version++; +master = replTest.getMaster(); +try { + master.getDB("admin").runCommand({replSetReconfig : config}); +} +catch (e) { + print(e); +} + +var config = master.getDB("local").system.replset.findOne(); +assert.eq(oldVersion+1, config.version); + +replTest.stopSet(); + +replTest2 = new ReplSetTest({name : 'testSet2', nodes : 1}); +nodes = replTest2.startSet(); + +result = nodes[0].getDB("admin").runCommand({replSetInitiate : {_id : "testSet2", members : [ + {_id : 0, tags : ["member0"]} + ]}}); + +assert(result.errmsg.match(/bad or missing host field/)); + +replTest2.stopSet(); diff --git a/jstests/replsets/remove1.js b/jstests/replsets/remove1.js index ebd17d6..f93fe9e 100644 --- a/jstests/replsets/remove1.js +++ b/jstests/replsets/remove1.js @@ -16,7 +16,7 @@ var host = getHostName(); print("Start set with three nodes"); -var replTest = new ReplSetTest( {name: name, nodes: 3} ); +var replTest = new ReplSetTest( {name: name, nodes: 2} ); var nodes = replTest.startSet(); replTest.initiate(); var master = replTest.getMaster(); @@ -28,85 +28,44 @@ master.getDB("foo").bar.baz.insert({x:1}); replTest.awaitReplication(); -print("Remove slave2"); +print("Remove slaves"); var config = replTest.getReplSetConfig(); config.members.pop(); config.version = 2; -try { - master.getDB("admin").runCommand({replSetReconfig:config}); -} -catch(e) { - print(e); -} -reconnect(master); - - -print("Remove slave1"); -config.members.pop(); -config.version = 3; -try { - master.getDB("admin").runCommand({replSetReconfig:config}); -} -catch(e) { - print(e); -} -reconnect(master); - -print("sleeping 1"); -sleep(10000); -// these are already down, but this clears their ports from memory so that they -// can be restarted later -stopMongod(replTest.getPort(1)); -stopMongod(replTest.getPort(2)); - - -print("Bring slave1 back up"); -var paths = [ replTest.getPath(1), replTest.getPath(2) ]; -var ports = allocatePorts(2, replTest.getPort(2)+1); -var args = ["mongod", "--port", ports[0], "--dbpath", paths[0], "--noprealloc", "--smallfiles", "--rest"]; -var conn = startMongoProgram.apply( null, args ); -conn.getDB("local").system.replset.remove(); -printjson(conn.getDB("local").runCommand({getlasterror:1})); -print(conn); -print("sleeping 2"); -sleep(10000); -stopMongod(ports[0]); - -replTest.restart(1); - - -print("Bring slave2 back up"); -args[2] = ports[1]; -args[4] = paths[1]; -conn = startMongoProgram.apply( null, args ); -conn.getDB("local").system.replset.remove(); -print("path: "+paths[1]); -print("sleeping 3"); -sleep(10000); -stopMongod(ports[1]); - -replTest.restart(2); -sleep(10000); - - -print("Add them back as slaves"); +assert.soon(function() { + try { + master.getDB("admin").runCommand({replSetReconfig:config}); + } + catch(e) { + print(e); + } + + reconnect(master); + reconnect(replTest.nodes[1]); + var c = master.getDB("local").system.replset.findOne(); + return c.version == 2; + }); + +print("Add it back as a slave"); config.members.push({_id:1, host : host+":"+replTest.getPort(1)}); -config.members.push({_id:2, host : host+":"+replTest.getPort(2)}); -config.version = 4; +config.version = 3; +printjson(config); wait(function() { try { - master.getDB("admin").runCommand({replSetReconfig:config}); + master.getDB("admin").runCommand({replSetReconfig:config}); } catch(e) { - print(e); + print(e); } reconnect(master); + printjson(master.getDB("admin").runCommand({replSetGetStatus:1})); master.setSlaveOk(); var newConfig = master.getDB("local").system.replset.findOne(); - return newConfig.version == 4; - }); + print( "newConfig: " + tojson(newConfig) ); + return newConfig.version == 3; +} , "wait1" ); print("Make sure everyone's secondary"); @@ -115,18 +74,49 @@ wait(function() { occasionally(function() { printjson(status); }); - - if (!status.members || status.members.length != 3) { + + if (!status.members || status.members.length != 2) { return false; } - for (var i = 0; i<3; i++) { + for (var i = 0; i<2; i++) { if (status.members[i].state != 1 && status.members[i].state != 2) { return false; } } return true; - }); +} , "wait2" ); + + +print("reconfig with minority"); +replTest.stop(1); + +assert.soon(function() { + try { + return master.getDB("admin").runCommand({isMaster : 1}).secondary; + } + catch(e) { + print("trying to get master: "+e); + } +}); + +config.version = 4; +config.members.pop(); +try { + master.getDB("admin").runCommand({replSetReconfig : config, force : true}); +} +catch(e) { + print(e); +} + +reconnect(master); +assert.soon(function() { + return master.getDB("admin").runCommand({isMaster : 1}).ismaster; +}); + +config = master.getDB("local").system.replset.findOne(); +printjson(config); +assert(config.version > 4); replTest.stopSet(); diff --git a/jstests/replsets/replset1.js b/jstests/replsets/replset1.js index 5ac94e7..6387c5d 100644 --- a/jstests/replsets/replset1.js +++ b/jstests/replsets/replset1.js @@ -108,6 +108,28 @@ doTest = function( signal ) { assert.eq( 1000 , count.n , "slave count wrong: " + slave ); }); + // last error + master = replTest.getMaster(); + slaves = replTest.liveNodes.slaves; + printjson(replTest.liveNodes); + + db = master.getDB("foo") + t = db.foo + + ts = slaves.map( function(z){ z.setSlaveOk(); return z.getDB( "foo" ).foo; } ) + + t.save({a: 1000}); + t.ensureIndex( { a : 1 } ) + + db.getLastError( 3 , 30000 ) + + ts.forEach( function(z){ assert.eq( 2 , z.getIndexKeys().length , "A " + z.getMongo() ); } ) + + t.reIndex() + + db.getLastError( 3 , 30000 ) + ts.forEach( function(z){ assert.eq( 2 , z.getIndexKeys().length , "A " + z.getMongo() ); } ) + // Shut down the set and finish the test. replTest.stopSet( signal ); } diff --git a/jstests/replsets/replset3.js b/jstests/replsets/replset3.js index faa0627..ba08eac 100644 --- a/jstests/replsets/replset3.js +++ b/jstests/replsets/replset3.js @@ -29,7 +29,7 @@ doTest = function (signal) { // Step down master. Note: this may close our connection!
try {
- master.getDB("admin").runCommand({ replSetStepDown: true });
+ master.getDB("admin").runCommand({ replSetStepDown: true, force: 1 });
} catch (err) {
print("caught: " + err + " on stepdown");
}
diff --git a/jstests/replsets/replset5.js b/jstests/replsets/replset5.js index 6a7d8a5..67ce2d7 100644 --- a/jstests/replsets/replset5.js +++ b/jstests/replsets/replset5.js @@ -23,51 +23,63 @@ doTest = function (signal) { master.getDB("barDB").bar.save({ a: 1 });
replTest.awaitReplication();
- // These writes should be replicated immediately - var docNum = 5000; - for(var n=0; n<docNum; n++) { - master.getDB(testDB).foo.insert({ n: n });
- } + // These writes should be replicated immediately
+ var docNum = 5000;
+ for (var n = 0; n < docNum; n++) {
+ master.getDB(testDB).foo.insert({ n: n });
+ }
- // If you want to test failure, just add values for w and wtimeout - // to the following command. This will override the default set above and - // prevent replication from happening in time for the count tests below. - master.getDB("admin").runCommand({getlasterror: 1});
+ // should use the configured last error defaults from above, that's what we're testing.
+ //
+ // If you want to test failure, just add values for w and wtimeout (e.g. w=1)
+ // to the following command. This will override the default set above and
+ // prevent replication from happening in time for the count tests below.
+ //
+ var result = master.getDB("admin").runCommand({ getlasterror: 1 });
+ print("replset5.js getlasterror result:");
+ printjson(result);
+
+ if (result.err == "timeout") {
+ print("\WARNING getLastError timed out and should not have.\nThis machine seems extremely slow. Stopping test without failing it\n")
+ replTest.stopSet(signal);
+ print("\WARNING getLastError timed out and should not have.\nThis machine seems extremely slow. Stopping test without failing it\n")
+ return;
+ }
var slaves = replTest.liveNodes.slaves;
slaves[0].setSlaveOk();
slaves[1].setSlaveOk();
- print("Testing slave counts");
+ print("replset5.js Testing slave counts");
+
+ var slave0count = slaves[0].getDB(testDB).foo.count();
+ assert(slave0count == docNum, "Slave 0 has " + slave0count + " of " + docNum + " documents!");
+
+ var slave1count = slaves[1].getDB(testDB).foo.count();
+ assert(slave1count == docNum, "Slave 1 has " + slave1count + " of " + docNum + " documents!");
+
+ var master1count = master.getDB(testDB).foo.count();
+ assert(master1count == docNum, "Master has " + master1count + " of " + docNum + " documents!");
+
+ print("replset5.js reconfigure with hidden=1");
+ config = master.getDB("local").system.replset.findOne();
+ config.version++;
+ config.members[2].priority = 0;
+ config.members[2].hidden = 1;
+
+ try {
+ master.adminCommand({ replSetReconfig: config });
+ }
+ catch (e) {
+ print(e);
+ }
+
+ config = master.getDB("local").system.replset.findOne();
+ printjson(config);
+ assert.eq(config.members[2].hidden, true);
- var slave0count = slaves[0].getDB(testDB).foo.count(); - assert( slave0count == docNum, "Slave 0 has " + slave0count + " of " + docNum + " documents!"); - - var slave1count = slaves[1].getDB(testDB).foo.count(); - assert( slave1count == docNum, "Slave 1 has " + slave1count + " of " + docNum + " documents!"); - - var master1count = master.getDB(testDB).foo.count(); - assert( master1count == docNum, "Master has " + master1count + " of " + docNum + " documents!"); - - print("reconfigure with hidden=1"); - config = master.getDB("local").system.replset.findOne(); - config.version++; - config.members[2].priority = 0; - config.members[2].hidden = 1; - - try { - master.adminCommand({replSetReconfig : config}); - } - catch(e) { - print(e); - } - - config = master.getDB("local").system.replset.findOne(); - printjson(config); - assert.eq(config.members[2].hidden, true); - replTest.stopSet(signal);
} -doTest( 15 );
-print("replset5.js success");
+doTest( 15 ); +print("replset5.js success"); diff --git a/jstests/replsets/replsetadd.js b/jstests/replsets/replsetadd.js index 673e1d7..44ef7c6 100644 --- a/jstests/replsets/replsetadd.js +++ b/jstests/replsets/replsetadd.js @@ -2,13 +2,17 @@ doTest = function( signal ) { // Test add node - var replTest = new ReplSetTest( {name: 'testSet', nodes: 0} ); + var replTest = new ReplSetTest( {name: 'testSet', nodes: 0, host:"localhost"} ); var first = replTest.add(); // Initiate replica set assert.soon(function() { - var res = first.getDB("admin").runCommand({replSetInitiate: null}); + var res = first.getDB("admin").runCommand({replSetInitiate: { + _id : 'testSet', + members : [{_id : 0, host : "localhost:"+replTest.ports[0]}] + } + }); return res['ok'] == 1; }); @@ -18,12 +22,36 @@ doTest = function( signal ) { return result['ok'] == 1; }); + replTest.getMaster(); + // Start a second node var second = replTest.add(); // Add the second node. // This runs the equivalent of rs.add(newNode); - replTest.reInitiate(); + print("calling add again"); + try { + replTest.reInitiate(); + } + catch(e) { + print(e); + } + + print("try to change to localhost to "+getHostName()); + var master = replTest.getMaster(); + + var config = master.getDB("local").system.replset.findOne(); + config.version++; + config.members.forEach(function(m) { + m.host = m.host.replace("localhost", getHostName()); + print(m.host); + }); + printjson(config); + + print("trying reconfig that shouldn't work"); + var result = master.getDB("admin").runCommand({replSetReconfig: config}); + assert.eq(result.ok, 0); + assert.eq(result.assertionCode, 13645); replTest.stopSet( signal ); } diff --git a/jstests/replsets/replsetarb1.js b/jstests/replsets/replsetarb1.js deleted file mode 100644 index a323290..0000000 --- a/jstests/replsets/replsetarb1.js +++ /dev/null @@ -1,33 +0,0 @@ -// FAILING TEST -// no primary is ever elected if the first server is an arbiter - -doTest = function( signal ) { - - var replTest = new ReplSetTest( {name: 'unicomplex', nodes: 3} ); - var nodes = replTest.nodeList(); - - print(tojson(nodes)); - - var conns = replTest.startSet(); - var r = replTest.initiate({"_id" : "unicomplex", - "members" : [ - {"_id" : 0, "host" : nodes[0], "arbiterOnly" : true}, - {"_id" : 1, "host" : nodes[1]}, - {"_id" : 2, "host" : nodes[2]}]}); - - // Make sure we have a master - // Neither this - var master = replTest.getMaster(); - - // Make sure we have an arbiter - // Nor this will succeed - assert.soon(function() { - res = conns[0].getDB("admin").runCommand({replSetGetStatus: 1}); - printjson(res); - return res.myState == 7; - }, "Aribiter failed to initialize."); - - replTest.stopSet( signal ); -} - -// doTest( 15 ); diff --git a/jstests/replsets/replsetarb2.js b/jstests/replsets/replsetarb2.js index 0e4c791..6f712cb 100644 --- a/jstests/replsets/replsetarb2.js +++ b/jstests/replsets/replsetarb2.js @@ -1,5 +1,4 @@ // Election when master fails and remaining nodes are an arbiter and a slave. -// Note that in this scenario, the arbiter needs two votes. doTest = function( signal ) { @@ -9,11 +8,11 @@ doTest = function( signal ) { print(tojson(nodes)); var conns = replTest.startSet(); - var r = replTest.initiate({"_id" : "unicomplex", + var r = replTest.initiate({"_id" : "unicomplex", "members" : [ - {"_id" : 0, "host" : nodes[0] }, - {"_id" : 1, "host" : nodes[1], "arbiterOnly" : true, "votes": 2}, - {"_id" : 2, "host" : nodes[2] }]}); + {"_id" : 0, "host" : nodes[0] }, + {"_id" : 1, "host" : nodes[1], "arbiterOnly" : true, "votes": 1, "priority" : 0}, + {"_id" : 2, "host" : nodes[2] }]}); // Make sure we have a master var master = replTest.getMaster(); @@ -25,6 +24,10 @@ doTest = function( signal ) { return res.myState == 7; }, "Aribiter failed to initialize."); + var result = conns[1].getDB("admin").runCommand({isMaster : 1}); + assert(result.arbiterOnly); + assert(!result.passive); + // Wait for initial replication master.getDB("foo").foo.insert({a: "foo"}); replTest.awaitReplication(); diff --git a/jstests/replsets/replsetarb3.js b/jstests/replsets/replsetarb3.js deleted file mode 100644 index 1193cf2..0000000 --- a/jstests/replsets/replsetarb3.js +++ /dev/null @@ -1,144 +0,0 @@ -// @file replsetarb3.js -// try turning arbiters into non-arbiters and vice versa - -/* - * 1: initialize set - * 2: check m3.state == 7 - * 3: reconfig - * 4: check m3.state == 2 - * 5: reconfig - * 6: check m3.state == 7 - * 7: reconfig - * 8: check m3.state == 2 - * 9: insert 10000 - * 10: reconfig - * 11: check m3.state == 7 - */ - -var debug = false; - -var statusSoon = function(s) { - assert.soon(function() { - var status = master.getDB("admin").runCommand({ replSetGetStatus: 1 }); - if (debug) - printjson(status); - return status.members[2].state == s; - }); -}; - -var w = 0; -var wait = function(f) { - w++; - var n = 0; - while (!f()) { - if( n % 4 == 0 ) - print("toostale.js waiting " + w); - if (++n == 4) { - print("" + f); - } - assert(n < 200, 'tried 200 times, giving up'); - sleep(1000); - } -} - -var reconnect = function(a) { - wait(function() { - try { - a.getDB("foo").bar.stats(); - return true; - } catch(e) { - print(e); - return false; - } - }); -}; - -var reconfig = function() { - config.version++; - try { - var result = master.getDB("admin").runCommand({replSetReconfig : config}); - } - catch(e) { - print(e); - } - reconnect(master); - reconnect(replTest.liveNodes.slaves[1]); - sleep(20000); -}; - -var replTest = new ReplSetTest( {name: 'unicomplex', nodes: 3} ); -var nodes = replTest.nodeList(); - -print(tojson(nodes)); - - -var conns = replTest.startSet(); - -print("1"); -var config = {"_id" : "unicomplex", "members" : [ - {"_id" : 0, "host" : nodes[0] }, - {"_id" : 1, "host" : nodes[1] }, - {"_id" : 2, "host" : nodes[2], "arbiterOnly" : true}]}; -var r = replTest.initiate(config); -config.version = 1; - -var master = replTest.getMaster(); - -// Wait for initial replication -master.getDB("foo").foo.insert({a: "foo"}); -replTest.awaitReplication(); - - -print("2"); -statusSoon(7); -assert.eq(replTest.liveNodes.slaves[1].getDB("local").oplog.rs.count(), 0); - -/* -print("3"); -delete config.members[2].arbiterOnly; -reconfig(); - - -print("4"); -statusSoon(2); -assert(replTest.liveNodes.slaves[1].getDB("local").oplog.rs.count() > 0); - - -print("5"); -config.members[2].arbiterOnly = true; -reconfig(); - - -print("6"); -statusSoon(7); -assert.eq(replTest.liveNodes.slaves[1].getDB("local").oplog.rs.count(), 0); - - -print("7"); -delete config.members[2].arbiterOnly; -reconfig(); - - -print("8"); -statusSoon(2); -assert(replTest.liveNodes.slaves[1].getDB("local").oplog.rs.count() > 0); - - -print("9"); -for (var i = 0; i < 10000; i++) { - master.getDB("foo").bar.insert({increment : i, c : 0, foo : "kasdlfjaklsdfalksdfakldfmalksdfmaklmfalkfmkafmdsaklfma", date : new Date(), d : Date()}); -} - - -print("10"); -config.members[2].arbiterOnly = true; -reconfig(); - - -print("11"); -statusSoon(7); -assert.eq(replTest.liveNodes.slaves[1].getDB("local").oplog.rs.count(), 0); -*/ - -replTest.stopSet( 15 ); - diff --git a/jstests/replsets/replsetfreeze.js b/jstests/replsets/replsetfreeze.js index 3721ba5..7096349 100644 --- a/jstests/replsets/replsetfreeze.js +++ b/jstests/replsets/replsetfreeze.js @@ -53,7 +53,7 @@ var master = replTest.getMaster(); print("2: step down m1"); try { - master.getDB("admin").runCommand({replSetStepDown : 1}); + master.getDB("admin").runCommand({replSetStepDown : 1, force : 1}); } catch(e) { print(e); @@ -80,7 +80,7 @@ master = replTest.getMaster(); print("6: step down new master"); try { - master.getDB("admin").runCommand({replSetStepDown : 1}); + master.getDB("admin").runCommand({replSetStepDown : 1, force : 1}); } catch(e) { print(e); diff --git a/jstests/replsets/replsetrestart1.js b/jstests/replsets/replsetrestart1.js index 65adaf4..d9f5093 100644 --- a/jstests/replsets/replsetrestart1.js +++ b/jstests/replsets/replsetrestart1.js @@ -22,9 +22,16 @@ doTest = function( signal ) { s1Id = replTest.getNodeId( replTest.liveNodes.slaves[0] ); s2Id = replTest.getNodeId( replTest.liveNodes.slaves[1] ); - replTest.stop( mId ); replTest.stop( s1Id ); replTest.stop( s2Id ); + + assert.soon(function() { + var status = master.getDB("admin").runCommand({replSetGetStatus: 1}); + return status.members[1].state == 8 && status.members[2].state == 8; + }); + + + replTest.stop( mId ); // Now let's restart these nodes replTest.restart( mId ); @@ -35,6 +42,11 @@ doTest = function( signal ) { master = replTest.getMaster(); slaves = replTest.liveNodes.slaves; + assert.soon(function() { + var status = master.getDB("admin").runCommand({replSetGetStatus: 1}); + return status.members[1].state != 8 && status.members[2].state != 8; + }); + // Do a status check on each node // Master should be set to 1 (primary) assert.soon(function() { diff --git a/jstests/replsets/replsetrestart2.js b/jstests/replsets/replsetrestart2.js index 324bd37..6d96697 100644 --- a/jstests/replsets/replsetrestart2.js +++ b/jstests/replsets/replsetrestart2.js @@ -1,16 +1,16 @@ // config saved on shutdown var compare_configs = function(c1, c2) { - assert(c1.version == c2.version, 'version same'); - assert(c1._id == c2._id, '_id same'); + assert.eq(c1.version, c2.version, 'version same'); + assert.eq(c1._id, c2._id, '_id same'); printjson(c1); printjson(c2); for (var i in c1.members) { assert(c2.members[i] !== undefined, 'field '+i+' exists in both configs'); - assert(c1.members[i]._id == c2.members[i]._id, 'id is equal in both configs'); - assert(c1.members[i].host == c2.members[i].host, 'id is equal in both configs'); + assert.eq(c1.members[i]._id, c2.members[i]._id, 'id is equal in both configs'); + assert.eq(c1.members[i].host, c2.members[i].host, 'id is equal in both configs'); } } diff --git a/jstests/replsets/rollback2.js b/jstests/replsets/rollback2.js index 46fb548..7ab3c6b 100644 --- a/jstests/replsets/rollback2.js +++ b/jstests/replsets/rollback2.js @@ -202,9 +202,24 @@ doTest = function (signal) { wait(function () { return B.isMaster().ismaster || B.isMaster().secondary; }); // everyone is up here... - assert(A.isMaster().ismaster || A.isMaster().secondary, "A up"); - assert(B.isMaster().ismaster || B.isMaster().secondary, "B up"); replTest.awaitReplication(); + + // theoretically, a read could slip in between StateBox::change() printing + // replSet SECONDARY + // and the replset actually becoming secondary + // so we're trying to wait for that here + print("waiting for secondary"); + assert.soon(function() { + try { + var aim = A.isMaster(); + var bim = B.isMaster(); + return (aim.ismaster || aim.secondary) && + (bim.ismaster || bim.secondary); + } + catch(e) { + print("checking A and B: "+e); + } + }); verify(a); diff --git a/jstests/replsets/rollback4.js b/jstests/replsets/rollback4.js new file mode 100644 index 0000000..5d3299b --- /dev/null +++ b/jstests/replsets/rollback4.js @@ -0,0 +1,117 @@ +//Test for SERVER-3650 (rollback from slave) +if (0) { // enable for SERVER-3772 + +var num = 7; +var host = getHostName(); +var name = "rollback4"; + +var replTest = new ReplSetTest( {name: name, nodes: num} ); +var config = replTest.getReplSetConfig(); + +// set preferred masters +config.members[0].priority = 3 +config.members[6].priority = 2 +// all other are 1 + +var nodes = replTest.startSet(); +replTest.initiate(config); +replTest.awaitReplication() +replTest.bridge(); + +replTest.waitForMaster(); +var master = replTest.getMaster(); +printjson(master.adminCommand("replSetGetStatus")); + +var mColl = master.getCollection('test.foo'); + +mColl.insert({}); +printjson(master.adminCommand("replSetGetStatus")); +printjson(master.adminCommand({getLastError:1, w:7, wtimeout:30*1000})); + +// partition 012 | 3456 with 0 and 6 the old and new master + + +printjson({startPartition: new Date()}); +replTest.partition(0,3) +replTest.partition(0,4) +replTest.partition(0,5) +replTest.partition(0,6) +replTest.partition(1,3) +replTest.partition(1,4) +replTest.partition(1,5) +replTest.partition(1,6) +replTest.partition(2,3) +replTest.partition(2,4) +replTest.partition(2,5) +replTest.partition(2,6) +printjson({endPartition: new Date()}); + +var gotThrough = 0 +try { + while (true){ + mColl.insert({}) + out = master.adminCommand({getLastError:1, w:3}); + if (out.err) + break; + + gotThrough++; + } +} +catch (e) { + print("caught exception"); +} + +printjson({gotThrough: gotThrough}); +printjson({cantWriteOldPrimary: new Date()}); +printjson(master.adminCommand("replSetGetStatus")); + +assert(gotThrough > 0, "gotOneThrough"); + +sleep(5*1000); // make sure new seconds field in opTime + +replTest.waitForMaster(); +var master2 = replTest.getMaster(); +printjson(master2.adminCommand("replSetGetStatus")); + +var m2Coll = master2.getCollection('test.foo'); + +var sentinel = {_id: 'sentinel'} // used to detect which master's data is used +m2Coll.insert(sentinel); +printjson(master2.adminCommand({getLastError:1, w:4, wtimeout:30*1000})); +printjson(master2.adminCommand("replSetGetStatus")); + +m2Coll.insert({}); // this shouldn't be necessary but the next GLE doesn't work without it + +printjson({startUnPartition: new Date()}); +replTest.unPartition(0,3) +replTest.unPartition(0,4) +replTest.unPartition(0,5) +replTest.unPartition(0,6) +replTest.unPartition(1,3) +replTest.unPartition(1,4) +replTest.unPartition(1,5) +replTest.unPartition(1,6) +replTest.unPartition(2,3) +replTest.unPartition(2,4) +replTest.unPartition(2,5) +replTest.unPartition(2,6) +printjson({endUnPartition: new Date()}); + +printjson(master2.adminCommand({getLastError:1, w:7, wtimeout:30*1000})); +printjson(master2.adminCommand("replSetGetStatus")); + +assert.soon(function() {return master.adminCommand('isMaster').ismaster}, + "Node 0 back to primary", + 60*1000/*needs to be longer than LeaseTime*/); +printjson(master.adminCommand("replSetGetStatus")); + +// make sure old master rolled back to new master +assert.eq(m2Coll.count(sentinel), 1, "check sentinal on node 6"); +assert.eq(mColl.count(sentinel), 1, "check sentinal on node 0"); + +replTest.stopSet(); + +} + + + diff --git a/jstests/replsets/rslib.js b/jstests/replsets/rslib.js index c072829..19271c9 100644 --- a/jstests/replsets/rslib.js +++ b/jstests/replsets/rslib.js @@ -2,7 +2,7 @@ var count = 0; var w = 0; -var wait = function(f) { +var wait = function(f,msg) { w++; var n = 0; while (!f()) { @@ -11,7 +11,7 @@ var wait = function(f) { if (++n == 4) { print("" + f); } - assert(n < 200, 'tried 200 times, giving up'); + assert(n < 200, 'tried 200 times, giving up on ' + msg ); sleep(1000); } }; @@ -61,3 +61,43 @@ var getLatestOp = function(server) { } return null; }; + + +var waitForAllMembers = function(master) { + var ready = false; + var count = 0; + + outer: + while (count < 60) { + count++; + var state = master.getSisterDB("admin").runCommand({replSetGetStatus:1}); + occasionally(function() { printjson(state); }, 10); + + for (var m in state.members) { + if (state.members[m].state != 2 && state.members[m].state != 1) { + sleep(1000); + continue outer; + } + } + return; + } + + assert(false, "all members not ready"); +}; + +var reconfig = function(rs, config) { + var admin = rs.getMaster().getDB("admin"); + + try { + var ok = admin.runCommand({replSetReconfig : config}); + assert.eq(ok.ok,1); + } + catch(e) { + print(e); + } + + master = rs.getMaster().getDB("admin"); + waitForAllMembers(master); + + return master; +}; diff --git a/jstests/replsets/slavedelay1.js b/jstests/replsets/slavedelay1.js index e549822..9301c8e 100644 --- a/jstests/replsets/slavedelay1.js +++ b/jstests/replsets/slavedelay1.js @@ -1,22 +1,4 @@ - -var waitForAllMembers = function(master) { - var ready = false; - - outer: - while (true) { - var state = master.getSisterDB("admin").runCommand({replSetGetStatus:1}); - printjson(state); - - for (var m in state.members) { - if (state.members[m].state != 2 && state.members[m].state != 1) { - sleep(10000); - continue outer; - } - } - return; - } -}; - +load("jstests/replsets/rslib.js"); doTest = function( signal ) { @@ -30,7 +12,7 @@ doTest = function( signal ) { /* set slaveDelay to 30 seconds */ var config = replTest.getReplSetConfig(); config.members[2].priority = 0; - config.members[2].slaveDelay = 30; + config.members[2].slaveDelay = 10; replTest.initiate(config); @@ -59,11 +41,16 @@ doTest = function( signal ) { // make sure delayed slave doesn't have it assert.eq(slave[1].foo.findOne(), null); - // wait 35 seconds - sleep(35000); - + for (var i=0; i<8; i++) { + assert.eq(slave[1].foo.findOne(), null); + sleep(1000); + } + // now delayed slave should have it - assert.eq(slave[1].foo.findOne().x, 1); + assert.soon(function() { + var z = slave[1].foo.findOne(); + return z && z.x == 1; + }); /************* Part 2 *******************/ @@ -79,9 +66,15 @@ doTest = function( signal ) { assert.eq(slave[0].foo.findOne({_id : 99}).foo, "bar"); assert.eq(slave[1].foo.findOne({_id : 99}), null); - sleep(35000); - - assert.eq(slave[1].foo.findOne({_id : 99}).foo, "bar"); + for (var i=0; i<8; i++) { + assert.eq(slave[1].foo.findOne({_id:99}), null); + sleep(1000); + } + + assert.soon(function() { + var z = slave[1].foo.findOne({_id : 99}); + return z && z.foo == "bar"; + }); /************* Part 3 *******************/ @@ -94,34 +87,53 @@ doTest = function( signal ) { config.version++; config.members.push({_id : 3, host : host+":31007",priority:0, slaveDelay:10}); - var admin = master.getSisterDB("admin"); - try { - var ok = admin.runCommand({replSetReconfig : config}); - assert.eq(ok.ok,1); - } - catch(e) { - print(e); - } - - master = replTest.getMaster().getDB(name); - - waitForAllMembers(master); - - sleep(15000); - + master = reconfig(replTest, config); + master = master.getSisterDB(name); + // it should be all caught up now master.foo.insert({_id : 123, "x" : "foo"}); master.runCommand({getlasterror:1,w:2}); conn.setSlaveOk(); - assert.eq(conn.getDB(name).foo.findOne({_id:123}), null); + + for (var i=0; i<8; i++) { + assert.eq(conn.getDB(name).foo.findOne({_id:123}), null); + sleep(1000); + } + + assert.soon(function() { + var z = conn.getDB(name).foo.findOne({_id:123}); + return z != null && z.x == "foo" + }); + + /************* Part 4 ******************/ - sleep(15000); + print("reconfigure slavedelay"); + + config.version++; + config.members[3].slaveDelay = 15; - assert.eq(conn.getDB(name).foo.findOne({_id:123}).x, "foo"); + master = reconfig(replTest, config); + master = master.getSisterDB(name); + assert.soon(function() { + return conn.getDB("local").system.replset.findOne().version == config.version; + }); + + master.foo.insert({_id : 124, "x" : "foo"}); + + for (var i=0; i<13; i++) { + assert.eq(conn.getDB(name).foo.findOne({_id:124}), null); + sleep(1000); + } + + assert.soon(function() { + var z = conn.getDB(name).foo.findOne({_id:124}); + return z != null && z.x == "foo" + }); + - replTest.stopSet(); + replTest.stopSet(); } doTest(15); diff --git a/jstests/replsets/stale_clustered.js b/jstests/replsets/stale_clustered.js new file mode 100644 index 0000000..457231e --- /dev/null +++ b/jstests/replsets/stale_clustered.js @@ -0,0 +1,101 @@ +// this tests that slaveOk'd queries in sharded setups get correctly routed when +// a slave goes into RECOVERING state, and don't break + +function prt(s) { + print("\nstale_clustered.js " + s); + print(); +} + +var shardTest = new ShardingTest( name = "clusteredstale" , + numShards = 2 , + verboseLevel = 0 , + numMongos = 2 , + otherParams = { rs : true } )//, + //rs0 : { logpath : "$path/mongod.log" }, + //rs1 : { logpath : "$path/mongod.log" } } ); + +shardTest.setBalancer( false ) + +var mongos = shardTest.s0 +var mongosSOK = shardTest.s1 +mongosSOK.setSlaveOk() + +var admin = mongos.getDB("admin") +var config = mongos.getDB("config") + +var dbase = mongos.getDB("test") +var coll = dbase.getCollection("foo") +var dbaseSOk = mongosSOK.getDB( "" + dbase ) +var collSOk = mongosSOK.getCollection( "" + coll ) + + +var rsA = shardTest._rs[0].test +var rsB = shardTest._rs[1].test + +rsA.getMaster().getDB( "test_a" ).dummy.insert( { x : 1 } ) +rsB.getMaster().getDB( "test_b" ).dummy.insert( { x : 1 } ) + +rsA.awaitReplication() +rsB.awaitReplication() + +prt("1: initial insert") + +coll.save({ _id : -1, a : "a", date : new Date() }) +coll.save({ _id : 1, b : "b", date : new Date() }) + +prt("2: shard collection") + +shardTest.shardGo( coll, /* shardBy */ { _id : 1 }, /* splitAt */ { _id : 0 } ) + +prt("3: test normal and slaveOk queries") + +// Make shardA and rsA the same +var shardA = shardTest.getShard( coll, { _id : -1 } ) +var shardAColl = shardA.getCollection( "" + coll ) +var shardB = shardTest.getShard( coll, { _id : 1 } ) + +if( shardA.name == rsB.getURL() ){ + var swap = rsB + rsB = rsA + rsA = swap +} + +rsA.awaitReplication() +rsB.awaitReplication() + +assert.eq( coll.find().itcount(), collSOk.find().itcount() ) +assert.eq( shardAColl.find().itcount(), 1 ) +assert.eq( shardAColl.findOne()._id, -1 ) + +prt("5: overflow oplog"); + +var secs = rsA.getSecondaries() +var goodSec = secs[0] +var badSec = secs[1] + +rsA.overflow( badSec ) + +prt("6: stop non-overflowed secondary") + +rsA.stop( goodSec, undefined, true ) + +prt("7: check our regular and slaveok query") + +assert.eq( coll.find().itcount(), collSOk.find().itcount() ) + +prt("8: restart both our secondaries clean") + +rsA.restart( rsA.getSecondaries(), { remember : true, startClean : true }, undefined, 5 * 60 * 1000 ) + +prt("9: wait for recovery") + +rsA.waitForState( rsA.getSecondaries(), rsA.SECONDARY, 5 * 60 * 1000 ) + +prt("10: check our regular and slaveok query") + +assert.eq( coll.find().itcount(), collSOk.find().itcount() ) + +prt("DONE\n\n\n"); + +//shardTest.stop() + diff --git a/jstests/replsets/stepdown.js b/jstests/replsets/stepdown.js new file mode 100644 index 0000000..3a17b0e --- /dev/null +++ b/jstests/replsets/stepdown.js @@ -0,0 +1,142 @@ +/* check that on a loss of primary, another node doesn't assume primary if it is stale + we force a stepDown to test this + we use lock+fsync to force secondary to be stale +*/ + +var replTest = new ReplSetTest({ name: 'testSet', nodes: 2 }); +var nodes = replTest.startSet(); +replTest.initiate(); +var master = replTest.getMaster(); + +// do a write +print("\ndo a write"); +master.getDB("foo").bar.insert({x:1}); +replTest.awaitReplication(); + +// lock secondary +print("\nlock secondary"); +var locked = replTest.liveNodes.slaves[0]; +printjson( locked.getDB("admin").runCommand({fsync : 1, lock : 1}) ); + +print("\nwaiting 11ish seconds"); + +sleep(2000); + +for (var i = 0; i < 11; i++) { + // do another write + master.getDB("foo").bar.insert({x:i}); + sleep(1000); +} + +print("\n do stepdown that should not work"); + +// this should fail, so we don't need to try/catch +var result = master.getDB("admin").runCommand({replSetStepDown: 10}); +printjson(result); +assert.eq(result.ok, 0); + +print("\n do stepdown that should work"); +try { + master.getDB("admin").runCommand({replSetStepDown: 50, force : true}); +} +catch (e) { + print(e); +} + +var r2 = master.getDB("admin").runCommand({ismaster : 1}); +assert.eq(r2.ismaster, false); +assert.eq(r2.secondary, true); + +print("\nunlock"); +printjson(locked.getDB("admin").$cmd.sys.unlock.findOne()); + +print("\nreset stepped down time"); +master.getDB("admin").runCommand({replSetFreeze:0}); +master = replTest.getMaster(); + +print("\nmake 1 config with priorities"); +var config = master.getDB("local").system.replset.findOne(); +print("\nmake 2"); +config.version++; +config.members[0].priority = 2; +config.members[1].priority = 1; +// make sure 1 can stay master once 0 is down +config.members[0].votes = 0; +try { + master.getDB("admin").runCommand({replSetReconfig : config}); +} +catch (e) { + print(e); +} + +print("\nawait"); +replTest.awaitReplication(); + +master = replTest.getMaster(); +var firstMaster = master; +print("\nmaster is now "+firstMaster); + +try { + printjson(master.getDB("admin").runCommand({replSetStepDown : 100, force : true})); +} +catch (e) { + print(e); +} + +print("\nget a master"); +replTest.getMaster(); + +assert.soon(function() { + var secondMaster = replTest.getMaster(); + return firstMaster+"" != secondMaster+""; + }, 'making sure '+firstMaster+' isn\'t still master', 60000); + + +print("\ncheck shutdown command"); + +master = replTest.liveNodes.master; +var slave = replTest.liveNodes.slaves[0]; +var slaveId = replTest.getNodeId(slave); + +try { + slave.adminCommand({shutdown :1}) +} +catch (e) { + print(e); +} + +print("\nsleeping"); + +sleep(2000); + +print("\nrunning shutdown without force on master: "+master); + +result = replTest.getMaster().getDB("admin").runCommand({shutdown : 1, timeoutSecs : 3}); +assert.eq(result.ok, 0); + +print("\nsend shutdown command"); + +var currentMaster = replTest.getMaster(); +try { + printjson(currentMaster.getDB("admin").runCommand({shutdown : 1, force : true})); +} +catch (e) { + print(e); +} + +print("checking "+currentMaster+" is actually shutting down"); +assert.soon(function() { + try { + currentMaster.findOne(); + } + catch(e) { + return true; + } + return false; +}); + +print("\nOK 1"); + +replTest.stopSet(); + +print("OK 2"); diff --git a/jstests/replsets/stepdown2.js b/jstests/replsets/stepdown2.js new file mode 100755 index 0000000..591fea2 --- /dev/null +++ b/jstests/replsets/stepdown2.js @@ -0,0 +1,139 @@ +print("\nstepdown2.js"); + +var replTest = new ReplSetTest({ name: 'testSet', nodes: 2 }); +var nodes = replTest.startSet(); +replTest.initiate(); +var master = replTest.getMaster(); + +// do a write +print("\ndo a write"); +master.getDB("foo").bar.insert({x:1}); +replTest.awaitReplication(); + +// lock secondary +print("\nlock secondary"); +var locked = replTest.liveNodes.slaves[0]; +printjson( locked.getDB("admin").runCommand({fsync : 1, lock : 1}) ); + +print("\nwaiting 11ish seconds"); + +sleep(3003); + +for (var i = 0; i < 11; i++) { + // do another write + master.getDB("foo").bar.insert({x:i}); + sleep(1008); +} + +print("\n do stepdown that should not work"); + +// this should fail, so we don't need to try/catch +var result = master.getDB("admin").runCommand({replSetStepDown: 10}); +printjson(result); +assert.eq(result.ok, 0); + +print("\n do stepdown that should work"); +try { + master.getDB("admin").runCommand({replSetStepDown: 50, force : true}); +} +catch (e) { + print(e); +} + +var r2 = master.getDB("admin").runCommand({ismaster : 1}); +assert.eq(r2.ismaster, false); +assert.eq(r2.secondary, true); + +print("\nunlock"); +printjson(locked.getDB("admin").$cmd.sys.unlock.findOne()); + +print("\nreset stepped down time"); +master.getDB("admin").runCommand({replSetFreeze:0}); +master = replTest.getMaster(); + +print("\nmake 1 config with priorities"); +var config = master.getDB("local").system.replset.findOne(); +print("\nmake 2"); +config.version++; +config.members[0].priority = 2; +config.members[1].priority = 1; +// make sure 1 can stay master once 0 is down +config.members[0].votes = 0; +try { + master.getDB("admin").runCommand({replSetReconfig : config}); +} +catch (e) { + print(e); +} + +print("\nawait"); +replTest.awaitReplication(); + +master = replTest.getMaster(); +var firstMaster = master; +print("\nmaster is now "+firstMaster); + +try { + printjson(master.getDB("admin").runCommand({replSetStepDown : 100, force : true})); +} +catch (e) { + print(e); +} + +print("\nget a master"); +replTest.getMaster(); + +assert.soon(function() { + var secondMaster = replTest.getMaster(); + return firstMaster+"" != secondMaster+""; + }, 'making sure '+firstMaster+' isn\'t still master', 60000); + + +print("\ncheck shutdown command"); + +master = replTest.liveNodes.master; +var slave = replTest.liveNodes.slaves[0]; +var slaveId = replTest.getNodeId(slave); + +try { + slave.adminCommand({shutdown :1}) +} +catch (e) { + print(e); +} + +print("\nsleeping"); + +sleep(2000); + +print("\nrunning shutdown without force on master: "+master); + +result = replTest.getMaster().getDB("admin").runCommand({shutdown : 1, timeoutSecs : 3}); +assert.eq(result.ok, 0); + +print("\nsend shutdown command"); + +var currentMaster = replTest.getMaster(); +try { + printjson(currentMaster.getDB("admin").runCommand({shutdown : 1, force : true})); +} +catch (e) { + print(e); +} + +print("checking "+currentMaster+" is actually shutting down"); +assert.soon(function() { + try { + currentMaster.findOne(); + } + catch(e) { + return true; + } + return false; +}); + +print("\nOK 1 stepdown2.js"); + +replTest.stopSet(); + +print("\nOK 2 stepdown2.js"); diff --git a/jstests/replsets/sync1.js b/jstests/replsets/sync1.js index af16044..a090c1c 100644 --- a/jstests/replsets/sync1.js +++ b/jstests/replsets/sync1.js @@ -15,156 +15,172 @@ function pause(s) { sleep(4000); } } -}
-
-doTest = function (signal) {
-
- var replTest = new ReplSetTest({ name: 'testSet', nodes: 3 });
- var nodes = replTest.startSet({ oplogSize: "40" });
-
- sleep(5000);
-
- print("\nsync1.js ********************************************************************** part 0");
- replTest.initiate();
-
- // get master
- print("\nsync1.js ********************************************************************** part 1");
- var master = replTest.getMaster();
- print("\nsync1.js ********************************************************************** part 2");
- var dbs = [master.getDB("foo")];
-
- for (var i in nodes) {
- if (nodes[i] + "" == master + "") {
- continue;
- }
- dbs.push(nodes[i].getDB("foo"));
- nodes[i].setSlaveOk();
- }
-
- print("\nsync1.js ********************************************************************** part 3");
- dbs[0].bar.drop();
-
- print("\nsync1.js ********************************************************************** part 4");
- // slow things down a bit
- dbs[0].bar.ensureIndex({ x: 1 });
- dbs[0].bar.ensureIndex({ y: 1 });
- dbs[0].bar.ensureIndex({ z: 1 });
- dbs[0].bar.ensureIndex({ w: 1 });
-
- var ok = false;
- var inserts = 10000;
-
- print("\nsync1.js ********************************************************************** part 5");
-
- for (var i = 0; i < inserts; i++) {
- dbs[0].bar.insert({ x: "foo" + i, y: "bar" + i, z: i, w: "biz baz bar boo" });
- }
-
- var status;
- do {
- sleep(1000);
- status = dbs[0].getSisterDB("admin").runCommand({ replSetGetStatus: 1 });
- } while (status.members[1].state != 2 || status.members[2].state != 2);
-
- print("\nsync1.js ********************************************************************** part 6");
- dbs[0].getSisterDB("admin").runCommand({ replSetTest: 1, blind: true });
-
- print("\nsync1.js ********************************************************************** part 7");
-
- sleep(5000);
-
- var max1;
- var max2;
- var count = 0;
- while (1) {
- try {
- max1 = dbs[1].bar.find().sort({ z: -1 }).limit(1).next();
- max2 = dbs[2].bar.find().sort({ z: -1 }).limit(1).next();
- }
- catch (e) {
- print("\nsync1.js couldn't get max1/max2; retrying " + e);
- sleep(2000);
- count++;
- if (count == 50) {
- assert(false, "errored out 50 times");
- }
- continue;
- }
- break;
- }
-
- // wait for a new master to be elected
- sleep(5000);
- var newMaster;
-
- print("\nsync1.js ********************************************************************** part 9");
-
- for (var q = 0; q < 10; q++) {
- // figure out who is master now
- newMaster = replTest.getMaster();
- if (newMaster + "" != master + "")
- break;
- sleep(2000);
- if (q > 6) print("sync1.js zzz....");
- }
-
- assert(newMaster + "" != master + "", "new master is " + newMaster + ", old master was " + master);
-
- print("\nsync1.js new master is " + newMaster + ", old master was " + master);
-
- print("\nsync1.js ********************************************************************** part 9.1");
-
- count = 0;
- countExceptions = 0;
- do {
- try {
- max1 = dbs[1].bar.find().sort({ z: -1 }).limit(1).next();
- max2 = dbs[2].bar.find().sort({ z: -1 }).limit(1).next();
- }
- catch (e) {
- if (countExceptions++ > 300) {
- print("dbs[1]:");
- try {
- printjson(dbs[1].isMaster());
- printjson(dbs[1].bar.count());
+} + +doTest = function (signal) { + + var replTest = new ReplSetTest({ name: 'testSet', nodes: 3 }); + var nodes = replTest.startSet({ oplogSize: "40" }); + print("\nsync1.js ********************************************************************** part 0"); + replTest.initiate(); + + // get master + print("\nsync1.js ********************************************************************** part 1"); + var master = replTest.getMaster(); + print("\nsync1.js ********************************************************************** part 2"); + var dbs = [master.getDB("foo")]; + + for (var i in nodes) { + if (nodes[i] + "" == master + "") { + continue; + } + dbs.push(nodes[i].getDB("foo")); + nodes[i].setSlaveOk(); + } + + print("\nsync1.js ********************************************************************** part 3"); + dbs[0].bar.drop(); + + print("\nsync1.js ********************************************************************** part 4"); + // slow things down a bit + dbs[0].bar.ensureIndex({ x: 1 }); + dbs[0].bar.ensureIndex({ y: 1 }); + dbs[0].bar.ensureIndex({ z: 1 }); + dbs[0].bar.ensureIndex({ w: 1 }); + + var ok = false; + var inserts = 10000; + + print("\nsync1.js ********************************************************************** part 5"); + + for (var i = 0; i < inserts; i++) { + dbs[0].bar.insert({ x: "foo" + i, y: "bar" + i, z: i, w: "biz baz bar boo" }); + } + + var status; + var secondaries = 0; + var count = 0; + do { + sleep(1000); + status = dbs[0].getSisterDB("admin").runCommand({ replSetGetStatus: 1 }); + + occasionally(function() { + printjson(status); + }, 30); + + secondaries = 0; + secondaries += status.members[0].state == 2 ? 1 : 0; + secondaries += status.members[1].state == 2 ? 1 : 0; + secondaries += status.members[2].state == 2 ? 1 : 0; + count++; + } while (secondaries < 2 && count < 300); + + assert(count < 300); + + // Need to be careful here, allocating datafiles for the slaves can take a *long* time on slow systems + sleep(7000); + + print("\nsync1.js ********************************************************************** part 6"); + dbs[0].getSisterDB("admin").runCommand({ replSetTest: 1, blind: true }); + + print("\nsync1.js ********************************************************************** part 7"); + + sleep(5000); + // If we start getting error hasNext: false with done alloc datafile msgs - may need to up the sleep again in part 5 + + + var max1; + var max2; + var count = 0; + while (1) { + try { + max1 = dbs[1].bar.find().sort({ z: -1 }).limit(1).next(); + max2 = dbs[2].bar.find().sort({ z: -1 }).limit(1).next(); + } + catch (e) { + print("\nsync1.js couldn't get max1/max2; retrying " + e); + sleep(2000); + count++; + if (count == 50) { + assert(false, "errored out 50 times"); + } + continue; + } + break; + } + + // wait for a new master to be elected + sleep(5000); + var newMaster; + + print("\nsync1.js ********************************************************************** part 9"); + + for (var q = 0; q < 10; q++) { + // figure out who is master now + newMaster = replTest.getMaster(); + if (newMaster + "" != master + "") + break; + sleep(2000); + if (q > 6) print("sync1.js zzz...."); + } + + assert(newMaster + "" != master + "", "new master is " + newMaster + ", old master was " + master); + + print("\nsync1.js new master is " + newMaster + ", old master was " + master); + + print("\nsync1.js ********************************************************************** part 9.1"); + + count = 0; + countExceptions = 0; + do { + try { + max1 = dbs[1].bar.find().sort({ z: -1 }).limit(1).next(); + max2 = dbs[2].bar.find().sort({ z: -1 }).limit(1).next(); + } + catch (e) { + if (countExceptions++ > 300) { + print("dbs[1]:"); + try { + printjson(dbs[1].isMaster()); + printjson(dbs[1].bar.count()); printjson(dbs[1].adminCommand({replSetGetStatus : 1})); - }
- catch (e) { print(e); }
- print("dbs[2]:");
- try {
- printjson(dbs[2].isMaster());
- printjson(dbs[2].bar.count());
+ } + catch (e) { print(e); } + print("dbs[2]:"); + try { + printjson(dbs[2].isMaster()); + printjson(dbs[2].bar.count()); printjson(dbs[2].adminCommand({replSetGetStatus : 1})); - }
- catch (e) { print(e); }
- assert(false, "sync1.js too many exceptions, failing");
- }
- print("\nsync1.js: exception querying; will sleep and try again " + e);
- sleep(3000);
- continue;
- }
-
- print("\nsync1.js waiting for match " + count + " " + Date() + " z[1]:" + max1.z + " z[2]:" + max2.z);
-
- // printjson(max1);
- // printjson(max2);
-
- sleep(2000);
-
- count++;
- if (count == 100) {
- pause("fail phase 1");
- assert(false, "replsets/\nsync1.js fails timing out");
- replTest.stopSet(signal);
- return;
- }
- } while (max1.z != max2.z);
-
- // okay, now they're caught up. We have a max: max1.z
-
- print("\nsync1.js ********************************************************************** part 10");
-
- // now, let's see if rollback works
+ } + catch (e) { print(e); } + assert(false, "sync1.js too many exceptions, failing"); + } + print("\nsync1.js: exception querying; will sleep and try again " + e); + sleep(3000); + continue; + } + + print("\nsync1.js waiting for match " + count + " " + Date() + " z[1]:" + max1.z + " z[2]:" + max2.z); + + // printjson(max1); + // printjson(max2); + + sleep(2000); + + count++; + if (count == 100) { + pause("fail phase 1"); + assert(false, "replsets/\nsync1.js fails timing out"); + replTest.stopSet(signal); + return; + } + } while (max1.z != max2.z); + + // okay, now they're caught up. We have a max: max1.z + + print("\nsync1.js ********************************************************************** part 10"); + + // now, let's see if rollback works wait(function() { try { dbs[0].adminCommand({ replSetTest: 1, blind: false }); @@ -180,50 +196,50 @@ doTest = function (signal) { }); - dbs[0].getMongo().setSlaveOk();
- sleep(5000);
-
- // now this should resync
- print("\nsync1.js ********************************************************************** part 11");
- var max0 = null;
- count = 0;
- do {
- try {
- max0 = dbs[0].bar.find().sort({ z: -1 }).limit(1).next();
- max1 = dbs[1].bar.find().sort({ z: -1 }).limit(1).next();
- }
- catch (e) {
- print("\nsync1.js part 11 exception on bar.find() will sleep and try again " + e);
- sleep(2000);
- continue;
- }
-
- print("part 11");
- if (max0) {
- print("max0.z:" + max0.z);
- print("max1.z:" + max1.z);
- }
-
- sleep(2000);
-
- count++;
- if (count == 100) {
- printjson(dbs[0].isMaster());
+ dbs[0].getMongo().setSlaveOk(); + sleep(5000); + + // now this should resync + print("\nsync1.js ********************************************************************** part 11"); + var max0 = null; + count = 0; + do { + try { + max0 = dbs[0].bar.find().sort({ z: -1 }).limit(1).next(); + max1 = dbs[1].bar.find().sort({ z: -1 }).limit(1).next(); + } + catch (e) { + print("\nsync1.js part 11 exception on bar.find() will sleep and try again " + e); + sleep(2000); + continue; + } + + print("part 11"); + if (max0) { + print("max0.z:" + max0.z); + print("max1.z:" + max1.z); + } + + sleep(2000); + + count++; + if (count == 100) { + printjson(dbs[0].isMaster()); printjson(dbs[0].adminCommand({replSetGetStatus:1})); - printjson(dbs[1].isMaster());
+ printjson(dbs[1].isMaster()); printjson(dbs[1].adminCommand({replSetGetStatus:1})); - pause("FAIL part 11");
- assert(false, "replsets/\nsync1.js fails timing out");
- replTest.stopSet(signal);
- return;
- }
- //print("||||| count:" + count);
- //printjson(max0);
- } while (!max0 || max0.z != max1.z);
-
- print("\nsync1.js ********************************************************************** part 12");
- pause("\nsync1.js success");
- replTest.stopSet(signal);
+ pause("FAIL part 11"); + assert(false, "replsets/\nsync1.js fails timing out"); + replTest.stopSet(signal); + return; + } + //print("||||| count:" + count); + //printjson(max0); + } while (!max0 || max0.z != max1.z); + + print("\nsync1.js ********************************************************************** part 12"); + pause("\nsync1.js success"); + replTest.stopSet(signal); } if( 1 || debugging ) { diff --git a/jstests/replsets/sync2.js b/jstests/replsets/sync2.js new file mode 100644 index 0000000..9f6c205 --- /dev/null +++ b/jstests/replsets/sync2.js @@ -0,0 +1,48 @@ + +var replTest = new ReplSetTest({ name: 'testSet', nodes: 5 }); +var nodes = replTest.startSet({ oplogSize: "2" }); +replTest.initiate(); + +var master = replTest.getMaster(); +var config = master.getDB("local").system.replset.findOne(); +config.version++; +config.members[0].priority = 2; + +try { + master.getDB("admin").runCommand({replSetReconfig : config}); +} +catch(e) { + print(e); +} + +// initial sync +master.getDB("foo").bar.insert({x:1}); +replTest.awaitReplication(); + +master = replTest.bridge(); + +replTest.partition(0,4); +replTest.partition(1,2); +replTest.partition(2,3); +replTest.partition(3,1); + +// 4 is connected to 2 +replTest.partition(4,1); +replTest.partition(4,3); + +master.getDB("foo").bar.insert({x:1}); +replTest.awaitReplication(); + +var result = master.getDB("admin").runCommand({getLastError:1,w:5,wtimeout:1000}); +assert.eq(null, result.err, tojson(result)); + +// 4 is connected to 3 +replTest.partition(4,2); +replTest.unPartition(4,3); + +master.getDB("foo").bar.insert({x:1}); +replTest.awaitReplication(); + +result = master.getDB("admin").runCommand({getLastError:1,w:5,wtimeout:1000}); +assert.eq(null, result.err, tojson(result)); + diff --git a/jstests/replsets/tags.js b/jstests/replsets/tags.js new file mode 100644 index 0000000..4e73886 --- /dev/null +++ b/jstests/replsets/tags.js @@ -0,0 +1,154 @@ + +var num = 5; +var host = getHostName(); +var name = "tags"; + +var replTest = new ReplSetTest( {name: name, nodes: num, startPort:31000} ); +var nodes = replTest.startSet(); +var port = replTest.ports; +replTest.initiate({_id : name, members : + [ + {_id:0, host : host+":"+port[0], tags : {"server" : "0", "dc" : "ny", "ny" : "1", "rack" : "ny.rk1"}}, + {_id:1, host : host+":"+port[1], tags : {"server" : "1", "dc" : "ny", "ny" : "2", "rack" : "ny.rk1"}}, + {_id:2, host : host+":"+port[2], tags : {"server" : "2", "dc" : "ny", "ny" : "3", "rack" : "ny.rk2", "2" : "this"}}, + {_id:3, host : host+":"+port[3], tags : {"server" : "3", "dc" : "sf", "sf" : "1", "rack" : "sf.rk1"}}, + {_id:4, host : host+":"+port[4], tags : {"server" : "4", "dc" : "sf", "sf" : "2", "rack" : "sf.rk2"}}, + ], + settings : { + getLastErrorModes : { + "important" : {"dc" : 2, "server" : 3}, + "a machine" : {"server" : 1} + } + }}); + +var master = replTest.getMaster(); + +var config = master.getDB("local").system.replset.findOne(); + +printjson(config); +var modes = config.settings.getLastErrorModes; +assert.eq(typeof modes, "object"); +assert.eq(modes.important.dc, 2); +assert.eq(modes.important.server, 3); +assert.eq(modes["a machine"]["server"], 1); + +config.version++; +config.members[1].priority = 1.5; +config.members[2].priority = 2; +modes.rack = {"sf" : 1}; +modes.niceRack = {"sf" : 2}; +modes["a machine"]["2"] = 1; +modes.on2 = {"2" : 1} + +try { + master.getDB("admin").runCommand({replSetReconfig : config}); +} +catch(e) { + print(e); +} + +replTest.awaitReplication(); + +print("primary should now be 2"); +master = replTest.getMaster(); +config = master.getDB("local").system.replset.findOne(); +printjson(config); + +modes = config.settings.getLastErrorModes; +assert.eq(typeof modes, "object"); +assert.eq(modes.important.dc, 2); +assert.eq(modes.important.server, 3); +assert.eq(modes["a machine"]["server"], 1); +assert.eq(modes.rack["sf"], 1); +assert.eq(modes.niceRack["sf"], 2); + +print("bridging"); +replTest.bridge(); + +replTest.partition(0, 3); +replTest.partition(0, 4); +replTest.partition(1, 3); +replTest.partition(1, 4); +replTest.partition(2, 3); +replTest.partition(2, 4); +replTest.partition(3, 4); +print("done bridging"); + +print("test1"); +print("2 should be primary"); +master = replTest.getMaster(); + +printjson(master.getDB("admin").runCommand({replSetGetStatus:1})); + +var timeout = 20000; + +master.getDB("foo").bar.insert({x:1}); +var result = master.getDB("foo").runCommand({getLastError:1,w:"rack",wtimeout:timeout}); +printjson(result); +assert.eq(result.err, "timeout"); + +replTest.unPartition(1,4); + +print("test2"); +master.getDB("foo").bar.insert({x:1}); +result = master.getDB("foo").runCommand({getLastError:1,w:"rack",wtimeout:timeout}); +printjson(result); +assert.eq(result.err, null); + +print("test3"); +result = master.getDB("foo").runCommand({getLastError:1,w:"niceRack",wtimeout:timeout}); +printjson(result); +assert.eq(result.err, "timeout"); + +replTest.unPartition(3,4); + +print("test4"); +result = master.getDB("foo").runCommand({getLastError:1,w:"niceRack",wtimeout:timeout}); +printjson(result); +assert.eq(result.err, null); + +print("non-existent w"); +result = master.getDB("foo").runCommand({getLastError:1,w:"blahblah",wtimeout:timeout}); +printjson(result); +assert.eq(result.assertionCode, 14830); +assert.eq(result.ok, 0); + +print("test on2"); +master.getDB("foo").bar.insert({x:1}); +result = master.getDB("foo").runCommand({getLastError:1,w:"on2",wtimeout:0}); +printjson(result); +assert.eq(result.err, null); + +print("test two on the primary"); +master.getDB("foo").bar.insert({x:1}); +result = master.getDB("foo").runCommand({getLastError:1,w:"a machine",wtimeout:0}); +printjson(result); +assert.eq(result.err, null); + +print("test5"); +master.getDB("foo").bar.insert({x:1}); +result = master.getDB("foo").runCommand({getLastError:1,w:"important",wtimeout:timeout}); +printjson(result); +assert.eq(result.err, null); + +replTest.unPartition(1,3); + +replTest.partition(2, 0); +replTest.partition(2, 1); +replTest.stop(2); + +print("1 must become primary here because otherwise the other members will take too long timing out their old sync threads"); +master = replTest.getMaster(); + +print("test6"); +master.getDB("foo").bar.insert({x:1}); +result = master.getDB("foo").runCommand({getLastError:1,w:"niceRack",wtimeout:timeout}); +printjson(result); +assert.eq(result.err, null); + +print("test on2"); +master.getDB("foo").bar.insert({x:1}); +result = master.getDB("foo").runCommand({getLastError:1,w:"on2",wtimeout:timeout}); +printjson(result); +assert.eq(result.err, "timeout"); + diff --git a/jstests/replsets/tags2.js b/jstests/replsets/tags2.js new file mode 100644 index 0000000..16dfcdf --- /dev/null +++ b/jstests/replsets/tags2.js @@ -0,0 +1,44 @@ +// Change a getLastErrorMode from 2 to 3 servers + +var host = getHostName(); +var replTest = new ReplSetTest( {name: "rstag", nodes: 3, startPort: 31000} ); +var nodes = replTest.startSet(); +var ports = replTest.ports; +var conf = {_id : "rstag", version: 1, members : [ + {_id : 0, host : host+":"+ports[0], tags : {"backup" : "A"}}, + {_id : 1, host : host+":"+ports[1], tags : {"backup" : "B"}}, + {_id : 2, host : host+":"+ports[2], tags : {"backup" : "C"}} ], + settings : {getLastErrorModes : { + backedUp : {backup : 2} }} }; +replTest.initiate( conf ); +replTest.awaitReplication(); + +master = replTest.getMaster(); +var db = master.getDB("test"); +db.foo.insert( {x:1} ); +var result = db.runCommand( {getLastError:1, w:"backedUp", wtimeout:20000} ); +assert.eq (result.err, null); + +conf.version = 2; +conf.settings.getLastErrorModes.backedUp.backup = 3; +master.getDB("admin").runCommand( {replSetReconfig: conf} ); +replTest.awaitReplication(); + +master = replTest.getMaster(); +var db = master.getDB("test"); +db.foo.insert( {x:2} ); +var result = db.runCommand( {getLastError:1, w:"backedUp", wtimeout:20000} ); +assert.eq (result.err, null); + +conf.version = 3; +conf.members[0].priorty = 3; +conf.members[2].priorty = 0; +master.getDB("admin").runCommand( {replSetReconfig: conf} ); + +master = replTest.getMaster(); +var db = master.getDB("test"); +db.foo.insert( {x:3} ); +var result = db.runCommand( {getLastError:1, w:"backedUp", wtimeout:20000} ); +assert.eq (result.err, null); + +replTest.stopSet(); diff --git a/jstests/replsets/toostale.js b/jstests/replsets/toostale.js index 0b8da0d..08b1a9c 100644 --- a/jstests/replsets/toostale.js +++ b/jstests/replsets/toostale.js @@ -32,7 +32,7 @@ var wait = function(f) { } var reconnect = function(a) { - wait(function() { + wait(function() { try { a.bar.stats(); return true; @@ -46,9 +46,14 @@ var reconnect = function(a) { var name = "toostale" var replTest = new ReplSetTest( {name: name, nodes: 3}); +var host = getHostName(); var nodes = replTest.startSet(); -replTest.initiate(); +replTest.initiate({_id : name, members : [ + {_id : 0, host : host+":"+replTest.ports[0]}, + {_id : 1, host : host+":"+replTest.ports[1], arbiterOnly : true}, + {_id : 2, host : host+":"+replTest.ports[2]} +]}); var master = replTest.getMaster(); var mdb = master.getDB("foo"); @@ -60,7 +65,7 @@ mdb.foo.save({a: 1000}); print("2: initial sync"); replTest.awaitReplication(); -print("3: blind s2"); +print("3: stop s2"); replTest.stop(2); print("waiting until the master knows the slave is blind"); assert.soon(function() { return master.getDB("admin").runCommand({replSetGetStatus:1}).members[2].health == 0 }); @@ -82,7 +87,7 @@ while (count != prevCount) { } -print("5: unblind s2"); +print("5: restart s2"); replTest.restart(2); print("waiting until the master knows the slave is not blind"); assert.soon(function() { return master.getDB("admin").runCommand({replSetGetStatus:1}).members[2].health != 0 }); @@ -106,16 +111,17 @@ replTest.restart(2); print("8: check s2.state == 3"); -status = master.getDB("admin").runCommand({replSetGetStatus:1}); -while (status.state == 0) { - print("state is 0: "); - printjson(status); - sleep(1000); - status = master.getDB("admin").runCommand({replSetGetStatus:1}); -} +assert.soon(function() { + var status = master.getDB("admin").runCommand({replSetGetStatus:1}); + printjson(status); + return status.members && status.members[2].state == 3; +}); -printjson(status); -assert.eq(status.members[2].state, 3, 'recovering'); +print("make sure s2 doesn't become primary"); +replTest.stop(0); +sleep(20000); +printjson(replTest.nodes[2].getDB("admin").runCommand({isMaster : 1})); +printjson(replTest.nodes[2].getDB("admin").runCommand({replSetGetStatus : 1})); -replTest.stopSet(15); +//replTest.stopSet(15); diff --git a/jstests/replsets/twosets.js b/jstests/replsets/twosets.js deleted file mode 100644 index aae1113..0000000 --- a/jstests/replsets/twosets.js +++ /dev/null @@ -1,35 +0,0 @@ -// add a node from a different set to the current set -// I don't know what should happen here. - -doTest = function( signal ) { - - var orig = new ReplSetTest( {name: 'testSet', nodes: 3} ); - orig.startSet(); - orig.initiate(); - var master = orig.getMaster(); - - var interloper = new ReplSetTest( {name: 'testSet', nodes: 3, startPort : 31003} ); - interloper.startSet(); - interloper.initiate(); - - var conf = master.getDB("local").system.replset.findOne(); - - var nodes = interloper.nodeList(); - var host = nodes[0]; - var id = conf.members.length; - conf.members.push({_id : id, host : host}); - conf.version++; - - try { - var result = master.getDB("admin").runCommand({replSetReconfig : conf}); - } - catch(e) { - print(e); - } - - // now... stuff should blow up? - - sleep(10); -} - -doTest(15);
\ No newline at end of file |