1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
/**
* 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_persistence,
* ]
*/
(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();
}());
|