/* * 1. insert 100000 objects * 2. export to two dbpaths * 3. add one node w/fastsync * 4. check that we never get "errmsg" : "initial sync cloning db: whatever" * 5. check writes are replicated */ 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; } }); }; ports = allocatePorts( 4 ); var basename = "jstests_fastsync"; var basePath = "/data/db/" + basename; var hostname = getHostName(); var pargs = new MongodRunner( ports[ 0 ], basePath + "-p", false, false, ["--replSet", basename, "--oplogSize", 2], {no_bind : true} ); p = pargs.start(); 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], priority:2}]}; printjson(config); var result = admin.runCommand({replSetInitiate : config}); print("result:"); printjson(result); var count = 0; while (count < 10 && result.ok != 1) { count++; sleep(2000); result = admin.runCommand({replSetInitiate : config}); } assert(result.ok, tojson(result)); 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++) { foo.bar.insert({date : new Date(), x : i, str : "all the talk on the market"}); } print("total in foo: "+foo.bar.count()); print("2"); admin.runCommand( {fsync:1,lock:1} ); copyDbpath( basePath + "-p", basePath + "-s"+1 ); admin.$cmd.sys.unlock.findOne(); print("3"); 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; 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")); 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);