2015-12-03 18:23:44 +01:00
|
|
|
/**
|
|
|
|
* Test basic read committed functionality, including:
|
|
|
|
* - Writes with writeConcern 'majority' should be visible once the write completes.
|
|
|
|
* - With the only data-bearing secondary down, committed reads should not include newly inserted
|
|
|
|
* data.
|
|
|
|
* - When data-bearing node comes back up and catches up, writes should be readable.
|
|
|
|
*/
|
|
|
|
|
|
|
|
load("jstests/replsets/rslib.js"); // For startSetIfSupportsReadMajority.
|
|
|
|
|
2015-04-15 00:13:08 +02:00
|
|
|
(function() {
|
2016-03-09 18:17:50 +01:00
|
|
|
"use strict";
|
2015-04-15 00:13:08 +02:00
|
|
|
|
2016-03-02 14:10:41 +01:00
|
|
|
function log(arg) {
|
|
|
|
jsTest.log(tojson(arg));
|
|
|
|
}
|
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
// Set up a set and grab things for later.
|
|
|
|
var name = "read_committed";
|
|
|
|
var replTest =
|
|
|
|
new ReplSetTest({name: name, nodes: 3, nodeOptions: {enableMajorityReadConcern: ''}});
|
2015-10-05 21:32:48 +02:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
if (!startSetIfSupportsReadMajority(replTest)) {
|
|
|
|
jsTest.log("skipping test since storage engine doesn't support committed reads");
|
|
|
|
return;
|
|
|
|
}
|
2015-10-05 21:32:48 +02:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
var nodes = replTest.nodeList();
|
2016-03-02 14:10:41 +01:00
|
|
|
var config = {
|
2016-03-09 18:17:50 +01:00
|
|
|
"_id": name,
|
|
|
|
"members": [
|
|
|
|
{"_id": 0, "host": nodes[0]},
|
|
|
|
{"_id": 1, "host": nodes[1], priority: 0},
|
|
|
|
{"_id": 2, "host": nodes[2], arbiterOnly: true}
|
|
|
|
]
|
2016-03-02 14:10:41 +01:00
|
|
|
};
|
|
|
|
updateConfigIfNotDurable(config);
|
|
|
|
replTest.initiate(config);
|
2015-04-15 00:13:08 +02:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
// Get connections and collection.
|
|
|
|
var primary = replTest.getPrimary();
|
|
|
|
var secondary = replTest.liveNodes.slaves[0];
|
|
|
|
var secondaryId = replTest.getNodeId(secondary);
|
|
|
|
var db = primary.getDB(name);
|
|
|
|
var t = db[name];
|
2015-04-15 00:13:08 +02:00
|
|
|
|
2016-03-02 14:10:41 +01:00
|
|
|
function doRead(readConcern) {
|
|
|
|
readConcern.maxTimeMS = 3000;
|
|
|
|
var res = assert.commandWorked(t.runCommand('find', readConcern));
|
|
|
|
var docs = (new DBCommandCursor(db.getMongo(), res)).toArray();
|
|
|
|
assert.gt(docs.length, 0, "no docs returned!");
|
|
|
|
return docs[0].state;
|
|
|
|
}
|
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
function doDirtyRead() {
|
2016-03-02 14:10:41 +01:00
|
|
|
log("doing dirty read");
|
|
|
|
var ret = doRead({"readConcern": {"level": "local"}});
|
|
|
|
log("done doing dirty read.");
|
|
|
|
return ret;
|
2016-03-09 18:17:50 +01:00
|
|
|
}
|
2015-04-15 00:13:08 +02:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
function doCommittedRead() {
|
2016-03-02 14:10:41 +01:00
|
|
|
log("doing committed read");
|
|
|
|
var ret = doRead({"readConcern": {"level": "majority"}});
|
|
|
|
log("done doing committed read.");
|
|
|
|
return ret;
|
2016-03-09 18:17:50 +01:00
|
|
|
}
|
2015-04-15 00:13:08 +02:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
// Do a write, wait for it to replicate, and ensure it is visible.
|
|
|
|
assert.writeOK(
|
|
|
|
t.save({_id: 1, state: 0}, {writeConcern: {w: "majority", wtimeout: 60 * 1000}}));
|
|
|
|
assert.eq(doDirtyRead(), 0);
|
|
|
|
assert.eq(doCommittedRead(), 0);
|
2015-04-15 00:13:08 +02:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
replTest.stop(secondaryId);
|
2015-04-15 00:13:08 +02:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
// Do a write and ensure it is only visible to dirty reads
|
|
|
|
assert.writeOK(t.save({_id: 1, state: 1}));
|
|
|
|
assert.eq(doDirtyRead(), 1);
|
|
|
|
assert.eq(doCommittedRead(), 0);
|
2015-04-15 00:13:08 +02:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
// Try the committed read again after sleeping to ensure it doesn't only work for queries
|
|
|
|
// immediately after the write.
|
|
|
|
sleep(1000);
|
|
|
|
assert.eq(doCommittedRead(), 0);
|
2015-07-14 14:58:21 +02:00
|
|
|
|
2016-03-09 18:17:50 +01:00
|
|
|
// Restart the node and ensure the committed view is updated.
|
|
|
|
replTest.restart(secondaryId);
|
|
|
|
db.getLastError("majority", 60 * 1000);
|
|
|
|
assert.eq(doDirtyRead(), 1);
|
|
|
|
assert.eq(doCommittedRead(), 1);
|
2015-07-14 14:58:21 +02:00
|
|
|
|
2015-04-15 00:13:08 +02:00
|
|
|
}());
|