summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJudah Schvimer <judah@mongodb.com>2018-04-18 17:41:40 -0400
committerJudah Schvimer <judah@mongodb.com>2018-04-19 17:36:44 -0400
commitf39a2374e525e250dc145dfc36091038bb4a4fc0 (patch)
treee441566f05c6de79f41d303141b17cbf0e5787dc
parentffc12520c4ffbe816f7068637869bfca8761691c (diff)
downloadmongo-f39a2374e525e250dc145dfc36091038bb4a4fc0.tar.gz
SERVER-34529 Rollback via recover to timestamp respects createRollbackDataFiles parameter
-rw-r--r--jstests/replsets/rollback_creates_rollback_directory.js216
-rw-r--r--src/mongo/db/repl/rollback_impl.cpp14
2 files changed, 118 insertions, 112 deletions
diff --git a/jstests/replsets/rollback_creates_rollback_directory.js b/jstests/replsets/rollback_creates_rollback_directory.js
index 0de5e21f73e..c0af3044bac 100644
--- a/jstests/replsets/rollback_creates_rollback_directory.js
+++ b/jstests/replsets/rollback_creates_rollback_directory.js
@@ -8,114 +8,116 @@
// inital sync from, so no primary will be elected. This test induces such a scenario, so cannot be
// run on ephemeral storage engines.
// @tags: [requires_persistence]
-var testName = "rollback_creates_rollback_directory";
-var replTest = new ReplSetTest({name: testName, nodes: 3});
-var nodes = replTest.nodeList();
-
-var conns = replTest.startSet();
-var r = replTest.initiate({
- "_id": testName,
- "members": [
- {"_id": 0, "host": nodes[0], priority: 3},
- {"_id": 1, "host": nodes[1]},
- {"_id": 2, "host": nodes[2], arbiterOnly: true}
- ]
-});
-
-// Make sure we have a master
-replTest.waitForState(replTest.nodes[0], ReplSetTest.State.PRIMARY);
-var master = replTest.getPrimary();
-var a_conn = conns[0];
-var b_conn = conns[1];
-a_conn.setSlaveOk();
-b_conn.setSlaveOk();
-var A = a_conn.getDB("test");
-var B = b_conn.getDB("test");
-var AID = replTest.getNodeId(a_conn);
-var BID = replTest.getNodeId(b_conn);
-var Apath = MongoRunner.dataDir + "/" + testName + "-0/";
-var Bpath = MongoRunner.dataDir + "/" + testName + "-1/";
-assert(master == conns[0], "conns[0] assumed to be master");
-assert(a_conn.host == master.host);
-
-// 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.");
-
-var options = {writeConcern: {w: 2, wtimeout: ReplSetTest.kDefaultTimeoutMS}, upsert: true};
-assert.writeOK(A.foo.update({key: 'value1'}, {$set: {req: 'req'}}, options));
-replTest.stop(AID);
-
-master = replTest.getPrimary();
-assert(b_conn.host == master.host);
-options = {
- writeConcern: {w: 1, wtimeout: ReplSetTest.kDefaultTimeoutMS},
- upsert: true
-};
-assert.writeOK(B.foo.update({key: 'value1'}, {$set: {res: 'res'}}, options));
-replTest.stop(BID);
-replTest.restart(AID);
-master = replTest.getPrimary();
-assert(a_conn.host == master.host);
-options = {
- writeConcern: {w: 1, wtimeout: ReplSetTest.kDefaultTimeoutMS},
- upsert: true
-};
-assert.writeOK(A.foo.update({key: 'value2'}, {$set: {req: 'req'}}, options));
-replTest.restart(BID); // should rollback
-reconnect(B);
-
-print("BEFORE------------------");
-printjson(A.foo.find().toArray());
-
-replTest.awaitReplication();
-replTest.awaitSecondaryNodes();
-
-print("AFTER------------------");
-printjson(A.foo.find().toArray());
-
-assert.eq(2, A.foo.find().itcount());
-assert.eq('req', A.foo.findOne({key: 'value1'}).req);
-assert.eq(null, A.foo.findOne({key: 'value1'}).res);
-reconnect(B);
-assert.eq(2, B.foo.find().itcount());
-assert.eq('req', B.foo.findOne({key: 'value1'}).req);
-assert.eq(null, B.foo.findOne({key: 'value1'}).res);
-
-// check here for rollback files
-var rollbackDir = Bpath + "rollback/";
-assert(pathExists(rollbackDir), "rollback directory was not created!");
-
-// Verify data consistency between nodes.
-replTest.checkReplicatedDataHashes();
-replTest.checkOplogs();
-
-print(testName + ".js SUCCESS");
-replTest.stopSet(15);
-
-function wait(f) {
- var n = 0;
- while (!f()) {
- if (n % 4 == 0)
- print(testName + ".js waiting");
- if (++n == 4) {
- print("" + f);
+
+function runRollbackDirectoryTest(shouldCreateRollbackFiles) {
+ jsTestLog("Testing createRollbackDataFiles = " + shouldCreateRollbackFiles);
+ var testName = "rollback_creates_rollback_directory";
+ var replTest = new ReplSetTest({name: testName, nodes: 3});
+ var nodes = replTest.nodeList();
+
+ var conns =
+ replTest.startSet({setParameter: {createRollbackDataFiles: shouldCreateRollbackFiles}});
+ var r = replTest.initiate({
+ "_id": testName,
+ "members": [
+ {"_id": 0, "host": nodes[0], priority: 3},
+ {"_id": 1, "host": nodes[1]},
+ {"_id": 2, "host": nodes[2], arbiterOnly: true}
+ ],
+ });
+
+ // Make sure we have a master
+ replTest.waitForState(replTest.nodes[0], ReplSetTest.State.PRIMARY);
+ var master = replTest.getPrimary();
+ var a_conn = conns[0];
+ var b_conn = conns[1];
+ a_conn.setSlaveOk();
+ b_conn.setSlaveOk();
+ var A = a_conn.getDB("test");
+ var B = b_conn.getDB("test");
+ var AID = replTest.getNodeId(a_conn);
+ var BID = replTest.getNodeId(b_conn);
+ var Apath = MongoRunner.dataDir + "/" + testName + "-0/";
+ var Bpath = MongoRunner.dataDir + "/" + testName + "-1/";
+ assert(master == conns[0], "conns[0] assumed to be master");
+ assert(a_conn.host == master.host);
+
+ // 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.");
+
+ var options = {writeConcern: {w: 2, wtimeout: replTest.kDefaultTimeoutMS}, upsert: true};
+ assert.writeOK(A.foo.update({key: 'value1'}, {$set: {req: 'req'}}, options));
+ replTest.stop(AID);
+
+ master = replTest.getPrimary();
+ assert(b_conn.host == master.host);
+ options = {writeConcern: {w: 1, wtimeout: replTest.kDefaultTimeoutMS}, upsert: true};
+ assert.writeOK(B.foo.update({key: 'value1'}, {$set: {res: 'res'}}, options));
+ replTest.stop(BID);
+ replTest.restart(AID);
+ master = replTest.getPrimary();
+ assert(a_conn.host == master.host);
+ options = {writeConcern: {w: 1, wtimeout: replTest.kDefaultTimeoutMS}, upsert: true};
+ assert.writeOK(A.foo.update({key: 'value2'}, {$set: {req: 'req'}}, options));
+ replTest.restart(BID); // should rollback
+ reconnect(B);
+
+ print("BEFORE------------------");
+ printjson(A.foo.find().toArray());
+
+ replTest.awaitReplication();
+ replTest.awaitSecondaryNodes();
+
+ print("AFTER------------------");
+ printjson(A.foo.find().toArray());
+
+ assert.eq(2, A.foo.find().itcount());
+ assert.eq('req', A.foo.findOne({key: 'value1'}).req);
+ assert.eq(null, A.foo.findOne({key: 'value1'}).res);
+ reconnect(B);
+ assert.eq(2, B.foo.find().itcount());
+ assert.eq('req', B.foo.findOne({key: 'value1'}).req);
+ assert.eq(null, B.foo.findOne({key: 'value1'}).res);
+
+ // check here for rollback files
+ var rollbackDir = Bpath + "rollback/";
+ assert.eq(pathExists(rollbackDir), shouldCreateRollbackFiles);
+
+ // Verify data consistency between nodes.
+ replTest.checkReplicatedDataHashes();
+ replTest.checkOplogs();
+
+ print(testName + ".js SUCCESS");
+ replTest.stopSet(15);
+
+ function wait(f) {
+ var n = 0;
+ while (!f()) {
+ if (n % 4 == 0)
+ print(testName + ".js waiting");
+ if (++n == 4) {
+ print("" + f);
+ }
+ assert(n < 200, 'tried 200 times, giving up');
+ sleep(1000);
}
- assert(n < 200, 'tried 200 times, giving up');
- sleep(1000);
}
-}
-function reconnect(a) {
- wait(function() {
- try {
- a.bar.stats();
- return true;
- } catch (e) {
- print(e);
- return false;
- }
- });
+ function reconnect(a) {
+ wait(function() {
+ try {
+ a.bar.stats();
+ return true;
+ } catch (e) {
+ print(e);
+ return false;
+ }
+ });
+ }
}
+
+runRollbackDirectoryTest(false);
+runRollbackDirectoryTest(true);
diff --git a/src/mongo/db/repl/rollback_impl.cpp b/src/mongo/db/repl/rollback_impl.cpp
index db5eb8f209e..530e740c38f 100644
--- a/src/mongo/db/repl/rollback_impl.cpp
+++ b/src/mongo/db/repl/rollback_impl.cpp
@@ -176,11 +176,15 @@ Status RollbackImpl::runRollback(OperationContext* opCtx) {
}
_rollbackStats.rollbackId = _replicationProcess->getRollbackID();
- // Write a rollback file for each namespace that has documents that would be deleted by
- // rollback.
- status = _writeRollbackFiles(opCtx);
- if (!status.isOK()) {
- return status;
+ if (shouldCreateDataFiles()) {
+ // Write a rollback file for each namespace that has documents that would be deleted by
+ // rollback.
+ status = _writeRollbackFiles(opCtx);
+ if (!status.isOK()) {
+ return status;
+ }
+ } else {
+ log() << "Not writing rollback files. 'createRollbackDataFiles' set to false.";
}
// Recover to the stable timestamp.