mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
a little more test
This commit is contained in:
parent
6c28ed10ca
commit
7358999b68
@ -1,214 +1,220 @@
|
||||
// test rollback in replica sets
|
||||
|
||||
// try running as :
|
||||
//
|
||||
// mongo --nodb rollback.js | tee out | grep -v ^m31
|
||||
//
|
||||
|
||||
print("rollback3.js");
|
||||
|
||||
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);
|
||||
}
|
||||
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");
|
||||
// test rollback in replica sets
|
||||
|
||||
// try running as :
|
||||
//
|
||||
// mongo --nodb rollback.js | tee out | grep -v ^m31
|
||||
//
|
||||
|
||||
var debugging = 1;
|
||||
|
||||
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);
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
function doWritesToKeep2(db) {
|
||||
t = db.bar;
|
||||
t.insert({ txt: 'foo' });
|
||||
t.remove({ q: 70 });
|
||||
t.update({ q: 0 }, { $inc: { y: 33} });
|
||||
}
|
||||
// test roll back (drop) a whole database
|
||||
abc = db.getSisterDB("abc");
|
||||
abc.foo.insert({ x: 1 });
|
||||
abc.bar.insert({ y: 999 });
|
||||
|
||||
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);
|
||||
// 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 );
|
||||
|
||||
|
||||
doTest( 15 );
|
||||
|
Loading…
Reference in New Issue
Block a user