diff options
author | clang-format-7.0.1 <adam.martin@10gen.com> | 2019-07-26 18:20:35 -0400 |
---|---|---|
committer | ADAM David Alan Martin <adam.martin@10gen.com> | 2019-07-27 11:02:23 -0400 |
commit | 134a4083953270e8a11430395357fb70a29047ad (patch) | |
tree | dd428e1230e31d92b20b393dfdc17ffe7fa79cb6 /jstests/replsets/read_committed_after_rollback.js | |
parent | 1e46b5049003f427047e723ea5fab15b5a9253ca (diff) | |
download | mongo-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.js | 280 |
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(); }()); |