diff options
author | Antonin Kral <a.kral@bobek.cz> | 2010-09-24 19:01:03 +0200 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2010-09-24 19:01:03 +0200 |
commit | 0ad0c09511a04ebe837f2acb859d47f2aa4e038a (patch) | |
tree | 109babcb556f6c5884b77853120717f0617c7a1e /jstests/replsets | |
parent | 03e58f81cad8dd4cfcd1530f327116f0cff6ceb3 (diff) | |
download | mongodb-0ad0c09511a04ebe837f2acb859d47f2aa4e038a.tar.gz |
Imported Upstream version 1.6.3
Diffstat (limited to 'jstests/replsets')
-rw-r--r-- | jstests/replsets/randomcommands1.js | 29 | ||||
-rw-r--r-- | jstests/replsets/replset1.js | 3 | ||||
-rw-r--r-- | jstests/replsets/replset2.js | 242 | ||||
-rw-r--r-- | jstests/replsets/replset4.js | 71 | ||||
-rw-r--r-- | jstests/replsets/replset5.js | 72 | ||||
-rw-r--r-- | jstests/replsets/replset_remove_node.js | 17 | ||||
-rw-r--r-- | jstests/replsets/rollback.js | 30 | ||||
-rw-r--r-- | jstests/replsets/rollback2.js | 8 | ||||
-rwxr-xr-x | jstests/replsets/rollback3.js | 224 | ||||
-rw-r--r-- | jstests/replsets/sync1.js | 353 | ||||
-rwxr-xr-x | jstests/replsets/two_initsync.js | 93 |
11 files changed, 830 insertions, 312 deletions
diff --git a/jstests/replsets/randomcommands1.js b/jstests/replsets/randomcommands1.js new file mode 100644 index 0000000..c451e74 --- /dev/null +++ b/jstests/replsets/randomcommands1.js @@ -0,0 +1,29 @@ + +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/replset1.js b/jstests/replsets/replset1.js index 6a18dff..5ac94e7 100644 --- a/jstests/replsets/replset1.js +++ b/jstests/replsets/replset1.js @@ -112,4 +112,5 @@ doTest = function( signal ) { replTest.stopSet( signal ); } -doTest( 15 ); +doTest( 15 );
+print("replset1.js SUCCESS");
diff --git a/jstests/replsets/replset2.js b/jstests/replsets/replset2.js index eaa35ee..f18b467 100644 --- a/jstests/replsets/replset2.js +++ b/jstests/replsets/replset2.js @@ -1,111 +1,141 @@ - -doTest = function( signal ) { - - // FAILING TEST - // See below: - - // Test replication with getLastError - - // Replica set testing API - // Create a new replica set test. Specify set name and the number of nodes you want. - var replTest = new ReplSetTest( {name: 'testSet', nodes: 3} ); - - // call startSet() to start each mongod in the replica set - // this returns a list of nodes - var nodes = replTest.startSet(); - - // Call initiate() to send the replSetInitiate command - // This will wait for initiation - replTest.initiate(); - - // Call getMaster to return a reference to the node that's been - // elected master. - var master = replTest.getMaster(); - - // Wait for replication to a single node - master.getDB("test").bar.insert({n: 1}); - - // Wait for initial sync - replTest.awaitReplication(); - - var slaves = replTest.liveNodes.slaves; - slaves.forEach(function(slave) { slave.setSlaveOk(); }); - - var testDB = "repl-test"; - - var failed = false; - var callGetLastError = function(w, timeout, db) { - var result = master.getDB(db).getLastErrorObj( w , timeout ); - printjson( result ); - if(result['ok'] != 1) { - print("FAILURE"); - failed = true; - } - } - - // Test getlasterror with multiple inserts - // TEST FAILS HERE - print("**** Try inserting a multiple records -- first insert ****") - master.getDB(testDB).foo.insert({n: 1}); - master.getDB(testDB).foo.insert({n: 2}); - master.getDB(testDB).foo.insert({n: 3}); - callGetLastError(3, 10000, testDB); - - print("**** TEMP 1a ****") - - m1 = master.getDB(testDB).foo.findOne({n: 1}); - printjson( m1 ); - assert( m1['n'] == 1 , "Failed to save to master on multiple inserts"); - - print("**** TEMP 1b ****") - - var s0 = slaves[0].getDB(testDB).foo.findOne({n: 1}); - assert( s0['n'] == 1 , "Failed to replicate to slave 0 on multiple inserts"); - - var s1 = slaves[1].getDB(testDB).foo.findOne({n: 1}); - assert( s1['n'] == 1 , "Failed to replicate to slave 1 on multiple inserts"); - - - // Test getlasterror with a simple insert - print("**** Try inserting a single record ****") - master.getDB(testDB).dropDatabase(); - master.getDB(testDB).foo.insert({n: 1}); - callGetLastError(3, 10000, testDB); - - m1 = master.getDB(testDB).foo.findOne({n: 1}); - printjson( m1 ); - assert( m1['n'] == 1 , "Failed to save to master"); - - - var s0 = slaves[0].getDB(testDB).foo.findOne({n: 1}); - assert( s0['n'] == 1 , "Failed to replicate to slave 0"); - - var s1 = slaves[1].getDB(testDB).foo.findOne({n: 1}); - assert( s1['n'] == 1 , "Failed to replicate to slave 1"); - - - // Test getlasterror with large insert - print("**** Try inserting many records ****") - bigData = new Array(2000).toString() - for(var n=0; n<1000; n++) { - master.getDB(testDB).baz.insert({n: n, data: bigData}); +print("\n\nreplset2.js BEGIN");
+
+doTest = function (signal) {
+
+ // FAILING TEST
+ // See below:
+
+ // Test replication with getLastError
+
+ // Replica set testing API
+ // Create a new replica set test. Specify set name and the number of nodes you want.
+ var replTest = new ReplSetTest({ name: 'testSet', nodes: 3, oplogSize: 5 });
+
+ // call startSet() to start each mongod in the replica set
+ // this returns a list of nodes
+ var nodes = replTest.startSet();
+
+ // Call initiate() to send the replSetInitiate command
+ // This will wait for initiation
+ replTest.initiate();
+
+ var testDB = "repl-test";
+
+ // Call getMaster to return a reference to the node that's been
+ // elected master.
+ var master = replTest.getMaster();
+
+ // Wait for replication to a single node
+ master.getDB(testDB).bar.insert({ n: 1 });
+
+ // Wait for initial sync
+ replTest.awaitReplication();
+
+ var slaves = replTest.liveNodes.slaves;
+ slaves.forEach(function (slave) { slave.setSlaveOk(); });
+
+ var failed = false;
+ var callGetLastError = function (w, timeout, db) {
+ try {
+ var result = master.getDB(db).getLastErrorObj(w, timeout);
+ print("replset2.js getLastError result: " + tojson(result));
+ if (result['ok'] != 1) {
+ print("replset2.js FAILURE getlasterror not ok");
+ failed = true;
+ }
+ }
+ catch (e) {
+ print("\nreplset2.js exception in getLastError: " + e + '\n');
+ throw e;
+ }
+ }
+
+ // Test getlasterror with multiple inserts
+ // TEST FAILS HEREg
+ print("\n\nreplset2.js **** Try inserting a multiple records -- first insert ****")
+
+ printjson(master.getDB("admin").runCommand("replSetGetStatus"));
+
+ master.getDB(testDB).foo.insert({ n: 1 });
+ master.getDB(testDB).foo.insert({ n: 2 });
+ master.getDB(testDB).foo.insert({ n: 3 });
+
+ print("\nreplset2.js **** TEMP 1 ****")
+
+ printjson(master.getDB("admin").runCommand("replSetGetStatus"));
+
+ callGetLastError(3, 25000, testDB);
+
+ print("replset2.js **** TEMP 1a ****")
+
+ m1 = master.getDB(testDB).foo.findOne({ n: 1 });
+ printjson(m1);
+ assert(m1['n'] == 1, "replset2.js Failed to save to master on multiple inserts");
+
+ print("replset2.js **** TEMP 1b ****")
+
+ var s0 = slaves[0].getDB(testDB).foo.findOne({ n: 1 });
+ assert(s0['n'] == 1, "replset2.js Failed to replicate to slave 0 on multiple inserts");
+
+ var s1 = slaves[1].getDB(testDB).foo.findOne({ n: 1 });
+ assert(s1['n'] == 1, "replset2.js Failed to replicate to slave 1 on multiple inserts");
+
+ // Test getlasterror with a simple insert
+ print("replset2.js **** Try inserting a single record ****")
+ master.getDB(testDB).dropDatabase();
+ master.getDB(testDB).foo.insert({ n: 1 });
+ callGetLastError(3, 10000, testDB);
+
+ m1 = master.getDB(testDB).foo.findOne({ n: 1 });
+ printjson(m1);
+ assert(m1['n'] == 1, "replset2.js Failed to save to master");
+
+ s0 = slaves[0].getDB(testDB).foo.findOne({ n: 1 });
+ assert(s0['n'] == 1, "replset2.js Failed to replicate to slave 0");
+
+ s1 = slaves[1].getDB(testDB).foo.findOne({ n: 1 });
+ assert(s1['n'] == 1, "replset2.js Failed to replicate to slave 1");
+
+ // Test getlasterror with large insert
+ print("replset2.js **** Try inserting many records ****")
+ try { + bigData = new Array(2000).toString()
+ for (var n = 0; n < 1000; n++) {
+ master.getDB(testDB).baz.insert({ n: n, data: bigData });
+ }
+ callGetLastError(3, 60000, testDB);
+
+ print("replset2.js **** V1 ")
+
+ var verifyReplication = function (nodeName, collection) {
+ data = collection.findOne({ n: 1 });
+ assert(data['n'] == 1, "replset2.js Failed to save to " + nodeName);
+ data = collection.findOne({ n: 999 });
+ assert(data['n'] == 999, "replset2.js Failed to save to " + nodeName);
+ }
+
+ print("replset2.js **** V2 ")
+
+ verifyReplication("master", master.getDB(testDB).baz);
+ verifyReplication("slave 0", slaves[0].getDB(testDB).baz);
+ verifyReplication("slave 1", slaves[1].getDB(testDB).baz);
+
+ assert(failed == false, "replset2.js Replication with getLastError failed. See errors.");
} - callGetLastError(3, 60000, testDB); - - var verifyReplication = function(nodeName, collection) { - data = collection.findOne({n: 1}); - assert( data['n'] == 1 , "Failed to save to " + nodeName); - data = collection.findOne({n: 999}); - assert( data['n'] == 999 , "Failed to save to " + nodeName); + catch(e) { + print("ERROR: " + e); + print("Master oplog findOne:"); + printjson(master.getDB("local").oplog.rs.find().sort({"$natural": -1}).limit(1).next()); + print("Slave 0 oplog findOne:"); + printjson(slaves[0].getDB("local").oplog.rs.find().sort({"$natural": -1}).limit(1).next()); + print("Slave 1 oplog findOne:"); + printjson(slaves[1].getDB("local").oplog.rs.find().sort({"$natural": -1}).limit(1).next()); } - verifyReplication("master", master.getDB(testDB).baz); - verifyReplication("slave 0", slaves[0].getDB(testDB).baz); - verifyReplication("slave 1", slaves[1].getDB(testDB).baz); - - assert( failed == false, "Replication with getLastError failed. See errors." ); - - replTest.stopSet( signal ); +
+ replTest.stopSet(signal);
} -doTest( 15 ); +doTest( 15 );
+
+print("\nreplset2.js SUCCESS\n"); diff --git a/jstests/replsets/replset4.js b/jstests/replsets/replset4.js index 4f6c454..9b1f2e9 100644 --- a/jstests/replsets/replset4.js +++ b/jstests/replsets/replset4.js @@ -1,29 +1,44 @@ -doTest = function( signal ) { - - // Test orphaned master steps down - var replTest = new ReplSetTest( {name: 'testSet', nodes: 3} ); - - replTest.startSet(); - replTest.initiate(); - - var master = replTest.getMaster(); - - // Kill both slaves, simulating a network partition - var slaves = replTest.liveNodes.slaves; - for(var i=0; i<slaves.length; i++) { - var slave_id = replTest.getNodeId(slaves[i]); - replTest.stop( slave_id ); - } - - var result = master.getDB("admin").runCommand({ismaster: 1}); - printjson( result ); - assert.soon(function() { - var result = master.getDB("admin").runCommand({ismaster: 1}); - printjson( result ); - return (result['ok'] == 1 && result['ismaster'] == false); - }, "Master fails to step down when orphaned."); - - replTest.stopSet( signal ); -} - +doTest = function (signal) {
+
+ // Test orphaned master steps down
+ var replTest = new ReplSetTest({ name: 'testSet', nodes: 3 });
+
+ replTest.startSet();
+ replTest.initiate();
+
+ var master = replTest.getMaster();
+
+ // Kill both slaves, simulating a network partition
+ var slaves = replTest.liveNodes.slaves;
+ for (var i = 0; i < slaves.length; i++) {
+ var slave_id = replTest.getNodeId(slaves[i]);
+ replTest.stop(slave_id);
+ }
+
+ print("replset4.js 1");
+
+ var result = master.getDB("admin").runCommand({ ismaster: 1 });
+
+ print("replset4.js 2");
+ printjson(result);
+
+ assert.soon(
+ function () {
+ try {
+ var result = master.getDB("admin").runCommand({ ismaster: 1 });
+ return (result['ok'] == 1 && result['ismaster'] == false);
+ } catch (e) {
+ print("replset4.js caught " + e);
+ return false;
+ }
+ },
+ "Master fails to step down when orphaned."
+ );
+
+ print("replset4.js worked, stopping");
+ replTest.stopSet(signal);
+}
+
+print("replset4.js"); doTest( 15 ); +print("replset4.js SUCCESS"); diff --git a/jstests/replsets/replset5.js b/jstests/replsets/replset5.js new file mode 100644 index 0000000..fe1761e --- /dev/null +++ b/jstests/replsets/replset5.js @@ -0,0 +1,72 @@ +// rs test getlasterrordefaults
+
+doTest = function (signal) {
+
+ // Test getLastError defaults
+ var replTest = new ReplSetTest({ name: 'testSet', nodes: 3 });
+
+ var nodes = replTest.startSet();
+
+ // Initiate set with default for getLastError
+ var config = replTest.getReplSetConfig();
+ config.settings = {};
+ config.settings.getLastErrorDefaults = { 'w': 3, 'wtimeout': 20000 };
+
+ replTest.initiate(config);
+
+ //
+ var master = replTest.getMaster();
+ replTest.awaitSecondaryNodes();
+ var testDB = "foo";
+
+ // Initial replication
+ master.getDB("barDB").bar.save({ a: 1 });
+ replTest.awaitReplication();
+
+ // These writes should be replicated immediately
+ master.getDB(testDB).foo.insert({ n: 1 });
+ master.getDB(testDB).foo.insert({ n: 2 });
+ master.getDB(testDB).foo.insert({ n: 3 });
+
+ // *** NOTE ***: The default doesn't seem to be propogating. + // When I run getlasterror with no defaults, the slaves don't have the data:
+ // These getlasterror commands can be run individually to verify this. + //master.getDB("admin").runCommand({ getlasterror: 1, w: 3, wtimeout: 20000 });
+ master.getDB("admin").runCommand({getlasterror: 1});
+
+ var slaves = replTest.liveNodes.slaves;
+ slaves[0].setSlaveOk();
+ slaves[1].setSlaveOk();
+
+ print("Testing slave counts");
+
+ // These should all have 3 documents, but they don't always. + var master1count = master.getDB(testDB).foo.count(); + assert( master1count == 3, "Master has " + master1count + " of 3 documents!"); + + var slave0count = slaves[0].getDB(testDB).foo.count(); + assert( slave0count == 3, "Slave 0 has " + slave0count + " of 3 documents!"); + + var slave1count = slaves[1].getDB(testDB).foo.count(); + assert( slave1count == 3, "Slave 1 has " + slave1count + " of 3 documents!"); + + print("Testing slave 0");
+ + var s0 = slaves[0].getDB(testDB).foo.find();
+ assert(s0.next()['n']);
+ assert(s0.next()['n']);
+ assert(s0.next()['n']);
+
+ print("Testing slave 1");
+
+ var s1 = slaves[1].getDB(testDB).foo.find();
+ assert(s1.next()['n']);
+ assert(s1.next()['n']);
+ assert(s1.next()['n']);
+
+ // End test
+ replTest.stopSet(signal);
+} + +doTest( 15 );
+print("replset5.js success");
diff --git a/jstests/replsets/replset_remove_node.js b/jstests/replsets/replset_remove_node.js index e06a951..fcb754c 100644 --- a/jstests/replsets/replset_remove_node.js +++ b/jstests/replsets/replset_remove_node.js @@ -27,8 +27,13 @@ doTest = function( signal ) { // Remove that node from the configuration replTest.remove( slaveId ); - // Then, reinitiate - replTest.reInitiate(); + // Now, re-initiate + var c = master.getDB("local")['system.replset'].findOne(); + var config = replTest.getReplSetConfig(); + config.version = c.version + 1; + config.members = [ { "_id" : 0, "host" : replTest.host + ":31000" }, + { "_id" : 2, "host" : replTest.host + ":31002" } ] + replTest.initiate( config , 'replSetReconfig' ); // Make sure that a new master comes up master = replTest.getMaster(); @@ -52,6 +57,8 @@ doTest = function( signal ) { stat = slaves[0].getDB("admin").runCommand({replSetGetStatus: 1}); return stat.members.length == 2; }, "Wrong number of members", 60000); -} - -doTest( 15 ); +}
+
+print("replset_remove_node.js");
+doTest(15);
+print("replset_remove_node SUCCESS");
diff --git a/jstests/replsets/rollback.js b/jstests/replsets/rollback.js index f072d61..8840371 100644 --- a/jstests/replsets/rollback.js +++ b/jstests/replsets/rollback.js @@ -28,7 +28,7 @@ function wait(f) { var n = 0;
while (!f()) {
if( n % 4 == 0 )
- print("waiting " + w);
+ print("rollback.js waiting " + w);
if (++n == 4) {
print("" + f);
}
@@ -72,6 +72,31 @@ doTest = function (signal) { // Wait for initial replication
var a = a_conn.getDB("foo");
var b = b_conn.getDB("foo");
+
+ /* force the oplog to roll */
+ if (new Date() % 2 == 0) {
+ print("ROLLING OPLOG AS PART OF TEST (we only do this sometimes)");
+ var pass = 1;
+ var first = a.getSisterDB("local").oplog.rs.find().sort({ $natural: 1 }).limit(1)[0];
+ a.roll.insert({ x: 1 });
+ while (1) {
+ for (var i = 0; i < 10000; i++)
+ a.roll.update({}, { $inc: { x: 1} });
+ var op = a.getSisterDB("local").oplog.rs.find().sort({ $natural: 1 }).limit(1)[0];
+ if (tojson(op.h) != tojson(first.h)) {
+ printjson(op);
+ printjson(first);
+ break;
+ }
+ pass++;
+ a.getLastError(2); // unlikely secondary isn't keeping up, but let's avoid possible intermittent issues with that.
+ }
+ print("PASSES FOR OPLOG ROLL: " + pass);
+ }
+ else {
+ print("NO ROLL");
+ }
+
a.bar.insert({ q: 1, a: "foo" });
a.bar.insert({ q: 2, a: "foo", x: 1 });
a.bar.insert({ q: 3, bb: 9, a: "foo" });
@@ -122,8 +147,9 @@ doTest = function (signal) { friendlyEqual(a.bar.find().sort({ _id: 1 }).toArray(), b.bar.find().sort({ _id: 1 }).toArray(), "server data sets do not match");
- pause("SUCCESS");
+ pause("rollback.js SUCCESS");
replTest.stopSet(signal);
} +print("rollback.js"); doTest( 15 ); diff --git a/jstests/replsets/rollback2.js b/jstests/replsets/rollback2.js index f9c48ff..483d221 100644 --- a/jstests/replsets/rollback2.js +++ b/jstests/replsets/rollback2.js @@ -27,8 +27,8 @@ function wait(f) { w++;
var n = 0;
while (!f()) {
- if( n % 4 == 0 )
- print("waiting " + w);
+ if (n % 4 == 0)
+ print("rollback2.js waiting " + w);
if (++n == 4) {
print("" + f);
}
@@ -192,8 +192,10 @@ doTest = function (signal) { assert( dbs_match(a,b), "server data sets do not match after rollback, something is wrong");
- pause("SUCCESS");
+ pause("rollback2.js SUCCESS");
replTest.stopSet(signal);
} +print("rollback2.js"); + doTest( 15 ); diff --git a/jstests/replsets/rollback3.js b/jstests/replsets/rollback3.js new file mode 100755 index 0000000..5c2f2f1 --- /dev/null +++ b/jstests/replsets/rollback3.js @@ -0,0 +1,224 @@ +// test rollback in replica sets + +// try running as : +// +// mongo --nodb rollback.js | tee out | grep -v ^m31 +// + +var debugging = 0; + +function pause(s) { + print(s); + while (debugging) { + sleep(3000); + print(s); + } +} + +function deb(obj) { + if( debugging ) { + print("\n\n\n" + obj + "\n\n"); + } +} + +w = 0; + +function wait(f) { + w++; + var n = 0; + while (!f()) { + if (n % 4 == 0) + print("rollback3.js waiting " + w); + if (++n == 4) { + print("" + f);
+ }
+ if (n == 200) {
+ print("rollback3.js failing waited too long");
+ throw "wait error"; + } + sleep(1000); + } +} + +function dbs_match(a, b) { + print("dbs_match"); + + var ac = a.system.namespaces.find().sort({name:1}).toArray(); + var bc = b.system.namespaces.find().sort({name:1}).toArray(); + if (!friendlyEqual(ac, bc)) { + print("dbs_match: namespaces don't match"); + print("\n\n"); + printjson(ac); + print("\n\n"); + printjson(bc); + print("\n\n"); + return false; + } + + var c = a.getCollectionNames(); + for( var i in c ) { + print("checking " + c[i]); + // system.indexes doesn't have _id so the more involved sort here: + if (!friendlyEqual(a[c[i]].find().sort({ _id: 1, ns:1, name:1 }).toArray(), b[c[i]].find().sort({ _id: 1, ns:1,name:1 }).toArray())) { + print("dbs_match: collections don't match " + c[i]); + if (a[c[i]].count() < 12) { + printjson(a[c[i]].find().sort({ _id: 1 }).toArray()); + printjson(b[c[i]].find().sort({ _id: 1 }).toArray()); + } + return false; + } + } + return true; +} + +/* these writes will be initial data and replicate everywhere. */ +function doInitialWrites(db) { + db.b.insert({ x: 1 }); + db.b.ensureIndex({ x: 1 }); + db.oldname.insert({ y: 1 }); + db.oldname.insert({ y: 2 }); + db.oldname.ensureIndex({ y: 1 },true); + t = db.bar; + t.insert({ q:0}); + t.insert({ q: 1, a: "foo" }); + t.insert({ q: 2, a: "foo", x: 1 }); + t.insert({ q: 3, bb: 9, a: "foo" }); + t.insert({ q: 40333333, a: 1 }); + for (var i = 0; i < 200; i++) t.insert({ i: i }); + t.insert({ q: 40, a: 2 }); + t.insert({ q: 70, txt: 'willremove' }); + + db.createCollection("kap", { capped: true, size: 5000 }); + db.kap.insert({ foo: 1 }) +} + +/* these writes on one primary only and will be rolled back. */ +function doItemsToRollBack(db) { + t = db.bar; + t.insert({ q: 4 }); + t.update({ q: 3 }, { q: 3, rb: true }); + + t.remove({ q: 40 }); // multi remove test + + t.update({ q: 2 }, { q: 39, rb: true }); + + // rolling back a delete will involve reinserting the item(s) + t.remove({ q: 1 }); + + t.update({ q: 0 }, { $inc: { y: 1} }); + + db.kap.insert({ foo: 2 }) + db.kap2.insert({ foo: 2 }) + + // create a collection (need to roll back the whole thing) + db.newcoll.insert({ a: true }); + + // create a new empty collection (need to roll back the whole thing) + db.createCollection("abc"); + + // drop a collection - we'll need all its data back! + t.drop(); + + // drop an index - verify it comes back + db.b.dropIndexes(); + + // two to see if we transitively rollback? + db.oldname.renameCollection("newname"); + db.newname.renameCollection("fooname"); + + assert(db.fooname.count() > 0, "count rename"); + + // test roll back (drop) a whole database + abc = db.getSisterDB("abc"); + abc.foo.insert({ x: 1 }); + abc.bar.insert({ y: 999 }); + + // test making and dropping a database + //mkd = db.getSisterDB("mkd"); + //mkd.c.insert({ y: 99 }); + //mkd.dropDatabase(); +} + +function doWritesToKeep2(db) { + t = db.bar; + t.insert({ txt: 'foo' }); + t.remove({ q: 70 }); + t.update({ q: 0 }, { $inc: { y: 33} }); +} + +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] }, + { "_id": 1, "host": nodes[1] }, + { "_id": 2, "host": nodes[2], arbiterOnly: true}] + }); + + // Make sure we have a master + var master = replTest.getMaster(); + a_conn = conns[0]; + A = a_conn.getDB("admin"); + b_conn = conns[1]; + a_conn.setSlaveOk(); + b_conn.setSlaveOk(); + B = b_conn.getDB("admin"); + assert(master == conns[0], "conns[0] assumed to be master"); + assert(a_conn == master); + + //deb(master); + + // Make sure we have an arbiter + assert.soon(function () { + res = conns[2].getDB("admin").runCommand({ replSetGetStatus: 1 }); + return res.myState == 7; + }, "Arbiter failed to initialize."); + + // Wait for initial replication + var a = a_conn.getDB("foo"); + var b = b_conn.getDB("foo"); + doInitialWrites(a); + + // wait for secondary to get this data + wait(function () { return b.bar.count() == a.bar.count(); }); + + A.runCommand({ replSetTest: 1, blind: true }); + wait(function () { return B.isMaster().ismaster; }); + + doItemsToRollBack(b); + + // a should not have the new data as it was in blind state. + B.runCommand({ replSetTest: 1, blind: true }); + A.runCommand({ replSetTest: 1, blind: false }); + wait(function () { return !B.isMaster().ismaster; }); + wait(function () { return A.isMaster().ismaster; }); + + assert(a.bar.count() >= 1, "count check"); + doWritesToKeep2(a); + + // A is 1 2 3 7 8 + // B is 1 2 3 4 5 6 + + // bring B back online + // as A is primary, B will roll back and then catch up + B.runCommand({ replSetTest: 1, blind: false }); + + 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"); + + assert( dbs_match(a,b), "server data sets do not match after rollback, something is wrong"); + + pause("rollback3.js SUCCESS"); + replTest.stopSet(signal); +} + +print("rollback3.js"); +doTest( 15 ); diff --git a/jstests/replsets/sync1.js b/jstests/replsets/sync1.js index 0f7754e..e60d128 100644 --- a/jstests/replsets/sync1.js +++ b/jstests/replsets/sync1.js @@ -2,8 +2,10 @@ var debugging=0; +w = 0; + function pause(s) { - // for debugging just to keep processes running
+ // for debugging just to keep processes running print("\nsync1.js: " + s); if (debugging) { while (1) { @@ -11,180 +13,197 @@ function pause(s) { sleep(4000); } } -} - -doTest = function (signal) { - +}
+
+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(); - +
+ 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"); + 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 = 100000; - - 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); - - // yay! there are out-of-date nodes - 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; - } - - print("\nsync1.js ********************************************************************** part 8"); - - if (max1.z == (inserts-1) && max2.z == (inserts-1)) { - print("\nsync1.js try increasing # if inserts and running again"); - replTest.stopSet(signal); - return; - } - - // wait for a new master to be elected - sleep(5000); - - // figure out who is master now - var newMaster = replTest.getMaster(); - - print("\nsync1.js ********************************************************************** part 9"); - - print("\nsync1.js \nsync1.js ********************************************************************** part 9 **********************************************");
+ 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 = 100000;
+
+ 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);
- - count = 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 ) { - print("\nsync1.js: exception querying; will sleep and try again " + e); - sleep(2000); - continue; - } - - print("\nsync1.js waiting for match " + count + " " + Date() + " z[1]:" + max1.z + " z[2]:" + max2.z); - +
+ 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());
+ }
+ catch (e) { print(e); }
+ print("dbs[2]:");
+ try {
+ printjson(dbs[2].isMaster());
+ printjson(dbs[2].bar.count());
+ }
+ 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: - var max = max1.z; - - print("\nsync1.js ********************************************************************** part 10"); - - // now, let's see if rollback works - var result = dbs[0].getSisterDB("admin").runCommand({ replSetTest: 1, blind: false }); - dbs[0].getMongo().setSlaveOk(); - - printjson(result); - sleep(5000); - - // FAIL! This never resyncs - // 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(); - } - catch(e) { - print("\nsync1.js part 11 exception on bar.find() will sleep and try again " + e); - sleep(2000); - continue; - } - - printjson(max); - printjson(max0); - print("\nsync1.js part 11 waiting for match " + count + " " + Date() + " z[0]:" + max0.z + " z:" + max); - - sleep(2000); - - count++; - if (count == 100) { - 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 != max); - - print("\nsync1.js ********************************************************************** part 12"); - pause("\nsync1.js success"); - replTest.stopSet(signal); +
+ 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
+ var result = dbs[0].getSisterDB("admin").runCommand({ replSetTest: 1, blind: false });
+ dbs[0].getMongo().setSlaveOk();
+
+ printjson(result);
+ 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) {
+ 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/two_initsync.js b/jstests/replsets/two_initsync.js new file mode 100755 index 0000000..6ae8475 --- /dev/null +++ b/jstests/replsets/two_initsync.js @@ -0,0 +1,93 @@ +// test initial sync failing + +// try running as : +// +// mongo --nodb two_initsync.js | tee out | grep -v ^m31 +// + +var debugging = 0; + +function pause(s) { + print(s); + while (debugging) { + sleep(3000); + print(s); + } +} + +function deb(obj) { + if( debugging ) { + print("\n\n\n" + obj + "\n\n"); + } +} + +w = 0; + +function wait(f) { + w++; + var n = 0; + while (!f()) { + if( n % 4 == 0 ) + print("twoinitsync waiting " + w); + if (++n == 4) { + print("" + f); + } + sleep(1000); + } +} + +doTest = function (signal) { + var replTest = new ReplSetTest({ name: 'testSet', nodes: 0 }); + + var first = replTest.add(); + + // Initiate replica set + assert.soon(function () { + var res = first.getDB("admin").runCommand({ replSetInitiate: null }); + return res['ok'] == 1; + }); + + // Get status + assert.soon(function () { + var result = first.getDB("admin").runCommand({ replSetGetStatus: true }); + return result['ok'] == 1; + }); + + var a = replTest.getMaster().getDB("two"); + for (var i = 0; i < 20000; i++) + a.coll.insert({ i: i, s: "a b" }); + + // Start a second node + var second = replTest.add(); + + // Add the second node. + // This runs the equivalent of rs.add(newNode); + replTest.reInitiate(); + + var b = second.getDB("admin"); + + // attempt to interfere with the initial sync + b._adminCommand({ replSetTest: 1, forceInitialSyncFailure: 1 }); + + // wait(function () { return a._adminCommand("replSetGetStatus").members.length == 2; }); + + wait(function () { return b.isMaster().secondary || b.isMaster().ismaster; }); + + print("b.isMaster:"); + printjson(b.isMaster()); + + second.setSlaveOk(); + + print("b.isMaster:"); + printjson(b.isMaster()); + + wait(function () { var c = b.getSisterDB("two").coll.count(); print(c); return c == 20000; }); + + print("two_initsync.js SUCCESS"); + + replTest.stopSet(signal); +} + + +print("two_initsync.js"); +doTest( 15 ); |