0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
mongodb/jstests/replsets/read_concern_snapshot_uses_committed.js

80 lines
3.0 KiB
JavaScript

/**
* Test that non-transaction snapshot reads only see committed data.
*
* Non-transaction snapshot reads with atClusterTime (or afterClusterTime) will wait for
* the majority commit point to move past the atClusterTime (or afterClusterTime) before they can
* read.
*
* @tags: [requires_majority_read_concern, requires_fcv_46]
*/
(function() {
"use strict";
load("jstests/libs/write_concern_util.js"); // For stopReplicationOnSecondaries.
const replSet = new ReplSetTest({nodes: [{}, {rsConfig: {priority: 0}}]});
replSet.startSet();
replSet.initiateWithHighElectionTimeout();
const dbName = "test";
const collName = "coll";
const primary = replSet.getPrimary();
const secondary = replSet.getSecondary();
const primaryDB = primary.getDB(dbName);
const secondaryDB = secondary.getDB(dbName);
const committedTimestamp =
assert.commandWorked(primaryDB.runCommand({insert: collName, documents: [{_id: 0}]}))
.operationTime;
replSet.awaitLastOpCommitted();
stopReplicationOnSecondaries(replSet);
// This document will not replicate.
const nonCommittedTimestamp =
assert.commandWorked(primaryDB.runCommand({insert: collName, documents: [{_id: 1}]}))
.operationTime;
for (let db of [primaryDB, secondaryDB]) {
jsTestLog(`Reading from ${db.getMongo()}`);
for (let readConcern of [{level: "snapshot"},
{level: "snapshot", atClusterTime: committedTimestamp},
{level: "snapshot", afterClusterTime: committedTimestamp}]) {
jsTestLog("Testing committed reads with readConcern " + tojson(readConcern));
// Only the replicated document is visible to snapshot read, even on primary.
let res = assert.commandWorked(db.runCommand({find: collName, readConcern: readConcern}));
assert.sameMembers(res.cursor.firstBatch, [{_id: 0}], tojson(res));
res = assert.commandWorked(db.runCommand(
{aggregate: collName, pipeline: [], cursor: {}, readConcern: readConcern}));
assert.sameMembers(res.cursor.firstBatch, [{_id: 0}], tojson(res));
}
for (let readConcern of [{level: "snapshot", atClusterTime: nonCommittedTimestamp},
{level: "snapshot", afterClusterTime: nonCommittedTimestamp}]) {
jsTestLog("Testing non-committed reads with readConcern " + tojson(readConcern));
// Test that snapshot reads ahead of the committed timestamp are blocked.
assert.commandFailedWithCode(db.runCommand({
find: collName,
readConcern: readConcern,
maxTimeMS: 1000,
}),
ErrorCodes.MaxTimeMSExpired);
assert.commandFailedWithCode(db.runCommand({
aggregate: collName,
pipeline: [],
cursor: {},
readConcern: readConcern,
maxTimeMS: 1000
}),
ErrorCodes.MaxTimeMSExpired);
}
}
restartReplicationOnSecondaries(replSet);
replSet.stopSet();
}());