summaryrefslogtreecommitdiff
path: root/jstests/replsets/read_committed_after_rollback.js
diff options
context:
space:
mode:
authorclang-format-7.0.1 <adam.martin@10gen.com>2019-07-26 18:20:35 -0400
committerADAM David Alan Martin <adam.martin@10gen.com>2019-07-27 11:02:23 -0400
commit134a4083953270e8a11430395357fb70a29047ad (patch)
treedd428e1230e31d92b20b393dfdc17ffe7fa79cb6 /jstests/replsets/read_committed_after_rollback.js
parent1e46b5049003f427047e723ea5fab15b5a9253ca (diff)
downloadmongo-134a4083953270e8a11430395357fb70a29047ad.tar.gz
SERVER-41772 Apply clang-format 7.0.1 to the codebase
Diffstat (limited to 'jstests/replsets/read_committed_after_rollback.js')
-rw-r--r--jstests/replsets/read_committed_after_rollback.js280
1 files changed, 138 insertions, 142 deletions
diff --git a/jstests/replsets/read_committed_after_rollback.js b/jstests/replsets/read_committed_after_rollback.js
index bdb83b144a8..097c75c1564 100644
--- a/jstests/replsets/read_committed_after_rollback.js
+++ b/jstests/replsets/read_committed_after_rollback.js
@@ -8,148 +8,144 @@
load("jstests/replsets/rslib.js"); // For startSetIfSupportsReadMajority.
(function() {
- "use strict";
-
- function assertCommittedReadsBlock(coll) {
- var res =
- coll.runCommand('find', {"readConcern": {"level": "majority"}, "maxTimeMS": 3000});
- assert.commandFailedWithCode(
- res,
- ErrorCodes.MaxTimeMSExpired,
- "Expected read of " + coll.getFullName() + ' on ' + coll.getMongo().host + " to block");
+"use strict";
+
+function assertCommittedReadsBlock(coll) {
+ var res = coll.runCommand('find', {"readConcern": {"level": "majority"}, "maxTimeMS": 3000});
+ assert.commandFailedWithCode(
+ res,
+ ErrorCodes.MaxTimeMSExpired,
+ "Expected read of " + coll.getFullName() + ' on ' + coll.getMongo().host + " to block");
+}
+
+function doCommittedRead(coll) {
+ var res = coll.runCommand('find', {"readConcern": {"level": "majority"}, "maxTimeMS": 10000});
+ assert.commandWorked(res, 'reading from ' + coll.getFullName() + ' on ' + coll.getMongo().host);
+ return new DBCommandCursor(coll.getDB(), res).toArray()[0].state;
+}
+
+function doDirtyRead(coll) {
+ var res = coll.runCommand('find', {"readConcern": {"level": "local"}});
+ assert.commandWorked(res, 'reading from ' + coll.getFullName() + ' on ' + coll.getMongo().host);
+ return new DBCommandCursor(coll.getDB(), res).toArray()[0].state;
+}
+
+// Set up a set and grab things for later.
+var name = "read_committed_after_rollback";
+var replTest = new ReplSetTest(
+ {name: name, nodes: 5, useBridge: true, nodeOptions: {enableMajorityReadConcern: ''}});
+
+if (!startSetIfSupportsReadMajority(replTest)) {
+ jsTest.log("skipping test since storage engine doesn't support committed reads");
+ replTest.stopSet();
+ return;
+}
+
+var nodes = replTest.nodeList();
+var config = {
+ "_id": name,
+ "members": [
+ {"_id": 0, "host": nodes[0]},
+ {"_id": 1, "host": nodes[1]},
+ {"_id": 2, "host": nodes[2], priority: 0},
+ // Note: using two arbiters to ensure that a host that can't talk to any other
+ // data-bearing node can still be elected. This also means that a write isn't considered
+ // committed until it is on all 3 data-bearing nodes, not just 2.
+ {"_id": 3, "host": nodes[3], arbiterOnly: true},
+ {"_id": 4, "host": nodes[4], arbiterOnly: true},
+ ]
+};
+
+replTest.initiate(config);
+
+// Get connections.
+var oldPrimary = replTest.getPrimary();
+var newPrimary = replTest._slaves[0];
+var pureSecondary = replTest._slaves[1];
+var arbiters = [replTest.nodes[3], replTest.nodes[4]];
+
+// This is the collection that all of the tests will use.
+var collName = name + '.collection';
+var oldPrimaryColl = oldPrimary.getCollection(collName);
+var newPrimaryColl = newPrimary.getCollection(collName);
+
+// Set up initial state.
+assert.writeOK(oldPrimaryColl.insert({_id: 1, state: 'old'},
+ {writeConcern: {w: 'majority', wtimeout: 30000}}));
+assert.eq(doDirtyRead(oldPrimaryColl), 'old');
+assert.eq(doCommittedRead(oldPrimaryColl), 'old');
+assert.eq(doDirtyRead(newPrimaryColl), 'old');
+// Note that we can't necessarily do a committed read from newPrimaryColl and get 'old', since
+// delivery of the commit level to secondaries isn't synchronized with anything
+// (we would have to hammer to reliably prove that it eventually would work).
+
+// Partition the world such that oldPrimary is still primary but can't replicate to anyone.
+// newPrimary is disconnected from the arbiters first to ensure that it can't be elected.
+newPrimary.disconnect(arbiters);
+oldPrimary.disconnect([newPrimary, pureSecondary]);
+assert.eq(doDirtyRead(newPrimaryColl), 'old');
+
+// This write will only make it to oldPrimary and will never become committed.
+assert.writeOK(oldPrimaryColl.save({_id: 1, state: 'INVALID'}));
+assert.eq(doDirtyRead(oldPrimaryColl), 'INVALID');
+assert.eq(doCommittedRead(oldPrimaryColl), 'old');
+
+// Change the partitioning so that oldPrimary is isolated, and newPrimary can be elected.
+oldPrimary.setSlaveOk();
+oldPrimary.disconnect(arbiters);
+newPrimary.reconnect(arbiters);
+assert.soon(() => newPrimary.adminCommand('isMaster').ismaster, '', 60 * 1000);
+assert.soon(function() {
+ try {
+ return !oldPrimary.adminCommand('isMaster').ismaster;
+ } catch (e) {
+ return false; // ignore disconnect errors.
}
-
- function doCommittedRead(coll) {
- var res =
- coll.runCommand('find', {"readConcern": {"level": "majority"}, "maxTimeMS": 10000});
- assert.commandWorked(res,
- 'reading from ' + coll.getFullName() + ' on ' + coll.getMongo().host);
- return new DBCommandCursor(coll.getDB(), res).toArray()[0].state;
+});
+
+// Stop applier on pureSecondary to ensure that writes to newPrimary won't become committed yet.
+assert.commandWorked(
+ pureSecondary.adminCommand({configureFailPoint: "rsSyncApplyStop", mode: "alwaysOn"}));
+assert.writeOK(newPrimaryColl.save({_id: 1, state: 'new'}));
+assert.eq(doDirtyRead(newPrimaryColl), 'new');
+// Note that we still can't do a committed read from the new primary and reliably get anything,
+// since we never proved that it learned about the commit level from the old primary before
+// the new primary got elected. The new primary cannot advance the commit level until it
+// commits a write in its own term. This includes learning that a majority of nodes have
+// received such a write.
+assert.eq(doCommittedRead(oldPrimaryColl), 'old');
+
+// Reconnect oldPrimary to newPrimary, inducing rollback of the 'INVALID' write. This causes
+// oldPrimary to clear its read majority point. oldPrimary still won't be connected to enough
+// hosts to allow it to be elected, so newPrimary should stay primary for the rest of this test.
+oldPrimary.reconnect(newPrimary);
+assert.soon(function() {
+ try {
+ return oldPrimary.adminCommand('isMaster').secondary &&
+ doDirtyRead(oldPrimaryColl) == 'new';
+ } catch (e) {
+ return false; // ignore disconnect errors.
}
-
- function doDirtyRead(coll) {
- var res = coll.runCommand('find', {"readConcern": {"level": "local"}});
- assert.commandWorked(res,
- 'reading from ' + coll.getFullName() + ' on ' + coll.getMongo().host);
- return new DBCommandCursor(coll.getDB(), res).toArray()[0].state;
- }
-
- // Set up a set and grab things for later.
- var name = "read_committed_after_rollback";
- var replTest = new ReplSetTest(
- {name: name, nodes: 5, useBridge: true, nodeOptions: {enableMajorityReadConcern: ''}});
-
- if (!startSetIfSupportsReadMajority(replTest)) {
- jsTest.log("skipping test since storage engine doesn't support committed reads");
- replTest.stopSet();
- return;
- }
-
- var nodes = replTest.nodeList();
- var config = {
- "_id": name,
- "members": [
- {"_id": 0, "host": nodes[0]},
- {"_id": 1, "host": nodes[1]},
- {"_id": 2, "host": nodes[2], priority: 0},
- // Note: using two arbiters to ensure that a host that can't talk to any other
- // data-bearing node can still be elected. This also means that a write isn't considered
- // committed until it is on all 3 data-bearing nodes, not just 2.
- {"_id": 3, "host": nodes[3], arbiterOnly: true},
- {"_id": 4, "host": nodes[4], arbiterOnly: true},
- ]
- };
-
- replTest.initiate(config);
-
- // Get connections.
- var oldPrimary = replTest.getPrimary();
- var newPrimary = replTest._slaves[0];
- var pureSecondary = replTest._slaves[1];
- var arbiters = [replTest.nodes[3], replTest.nodes[4]];
-
- // This is the collection that all of the tests will use.
- var collName = name + '.collection';
- var oldPrimaryColl = oldPrimary.getCollection(collName);
- var newPrimaryColl = newPrimary.getCollection(collName);
-
- // Set up initial state.
- assert.writeOK(oldPrimaryColl.insert({_id: 1, state: 'old'},
- {writeConcern: {w: 'majority', wtimeout: 30000}}));
- assert.eq(doDirtyRead(oldPrimaryColl), 'old');
- assert.eq(doCommittedRead(oldPrimaryColl), 'old');
- assert.eq(doDirtyRead(newPrimaryColl), 'old');
- // Note that we can't necessarily do a committed read from newPrimaryColl and get 'old', since
- // delivery of the commit level to secondaries isn't synchronized with anything
- // (we would have to hammer to reliably prove that it eventually would work).
-
- // Partition the world such that oldPrimary is still primary but can't replicate to anyone.
- // newPrimary is disconnected from the arbiters first to ensure that it can't be elected.
- newPrimary.disconnect(arbiters);
- oldPrimary.disconnect([newPrimary, pureSecondary]);
- assert.eq(doDirtyRead(newPrimaryColl), 'old');
-
- // This write will only make it to oldPrimary and will never become committed.
- assert.writeOK(oldPrimaryColl.save({_id: 1, state: 'INVALID'}));
- assert.eq(doDirtyRead(oldPrimaryColl), 'INVALID');
- assert.eq(doCommittedRead(oldPrimaryColl), 'old');
-
- // Change the partitioning so that oldPrimary is isolated, and newPrimary can be elected.
- oldPrimary.setSlaveOk();
- oldPrimary.disconnect(arbiters);
- newPrimary.reconnect(arbiters);
- assert.soon(() => newPrimary.adminCommand('isMaster').ismaster, '', 60 * 1000);
- assert.soon(function() {
- try {
- return !oldPrimary.adminCommand('isMaster').ismaster;
- } catch (e) {
- return false; // ignore disconnect errors.
- }
- });
-
- // Stop applier on pureSecondary to ensure that writes to newPrimary won't become committed yet.
- assert.commandWorked(
- pureSecondary.adminCommand({configureFailPoint: "rsSyncApplyStop", mode: "alwaysOn"}));
- assert.writeOK(newPrimaryColl.save({_id: 1, state: 'new'}));
- assert.eq(doDirtyRead(newPrimaryColl), 'new');
- // Note that we still can't do a committed read from the new primary and reliably get anything,
- // since we never proved that it learned about the commit level from the old primary before
- // the new primary got elected. The new primary cannot advance the commit level until it
- // commits a write in its own term. This includes learning that a majority of nodes have
- // received such a write.
- assert.eq(doCommittedRead(oldPrimaryColl), 'old');
-
- // Reconnect oldPrimary to newPrimary, inducing rollback of the 'INVALID' write. This causes
- // oldPrimary to clear its read majority point. oldPrimary still won't be connected to enough
- // hosts to allow it to be elected, so newPrimary should stay primary for the rest of this test.
- oldPrimary.reconnect(newPrimary);
- assert.soon(function() {
- try {
- return oldPrimary.adminCommand('isMaster').secondary &&
- doDirtyRead(oldPrimaryColl) == 'new';
- } catch (e) {
- return false; // ignore disconnect errors.
- }
- }, '', 60 * 1000);
- assert.eq(doDirtyRead(oldPrimaryColl), 'new');
-
- // Resume oplog application on pureSecondary to allow the 'new' write to be committed. It should
- // now be visible as a committed read to both oldPrimary and newPrimary.
- assert.commandWorked(
- pureSecondary.adminCommand({configureFailPoint: "rsSyncApplyStop", mode: "off"}));
- // Do a write to the new primary so that the old primary can establish a sync source to learn
- // about the new commit.
- assert.writeOK(newPrimary.getDB(name).unrelatedCollection.insert(
- {a: 1}, {writeConcern: {w: 'majority', wtimeout: replTest.kDefaultTimeoutMS}}));
- assert.eq(doCommittedRead(newPrimaryColl), 'new');
- // Do another write to the new primary so that the old primary can be sure to receive the
- // new committed optime.
- assert.writeOK(newPrimary.getDB(name).unrelatedCollection.insert(
- {a: 2}, {writeConcern: {w: 'majority', wtimeout: replTest.kDefaultTimeoutMS}}));
- assert.eq(doCommittedRead(oldPrimaryColl), 'new');
-
- // Verify data consistency between nodes.
- replTest.checkReplicatedDataHashes();
- replTest.checkOplogs();
- replTest.stopSet();
+}, '', 60 * 1000);
+assert.eq(doDirtyRead(oldPrimaryColl), 'new');
+
+// Resume oplog application on pureSecondary to allow the 'new' write to be committed. It should
+// now be visible as a committed read to both oldPrimary and newPrimary.
+assert.commandWorked(
+ pureSecondary.adminCommand({configureFailPoint: "rsSyncApplyStop", mode: "off"}));
+// Do a write to the new primary so that the old primary can establish a sync source to learn
+// about the new commit.
+assert.writeOK(newPrimary.getDB(name).unrelatedCollection.insert(
+ {a: 1}, {writeConcern: {w: 'majority', wtimeout: replTest.kDefaultTimeoutMS}}));
+assert.eq(doCommittedRead(newPrimaryColl), 'new');
+// Do another write to the new primary so that the old primary can be sure to receive the
+// new committed optime.
+assert.writeOK(newPrimary.getDB(name).unrelatedCollection.insert(
+ {a: 2}, {writeConcern: {w: 'majority', wtimeout: replTest.kDefaultTimeoutMS}}));
+assert.eq(doCommittedRead(oldPrimaryColl), 'new');
+
+// Verify data consistency between nodes.
+replTest.checkReplicatedDataHashes();
+replTest.checkOplogs();
+replTest.stopSet();
}());