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
83
84
85
86
87
88
|
/**
* Tests that replSetGetStatus responses include the last applied and durable wall times for other
* members.
*
* @tags: [multiversion_incompatible]
*/
(function() {
"use strict";
load("jstests/libs/write_concern_util.js");
load("jstests/replsets/rslib.js");
// We use GTE to account for the possibility of other writes in the system (e.g. HMAC).
// Comparison is GTE by default, GT if 'strict' is specified.
function checkWallTimes(primary, greaterMemberIndex, lesserMemberIndex, strict = false) {
assert.soonNoExcept(function() {
let res = assert.commandWorked(primary.adminCommand({replSetGetStatus: 1}));
assert(res.members, () => tojson(res));
const greater = res.members[greaterMemberIndex];
assert(greater, () => tojson(res));
const greaterApplied = greater.lastAppliedWallTime;
const greaterDurable = greater.lastAppliedWallTime;
assert(greaterApplied, () => tojson(res));
assert(greaterDurable, () => tojson(res));
const lesser = res.members[lesserMemberIndex];
assert(lesser, () => tojson(res));
const lesserApplied = lesser.lastAppliedWallTime;
const lesserDurable = lesser.lastDurableWallTime;
assert(lesser.lastAppliedWallTime, () => tojson(res));
assert(lesser.lastDurableWallTime, () => tojson(res));
if (!strict) {
assert.gte(greaterApplied, lesserApplied, () => tojson(res));
assert.gte(greaterDurable, lesserDurable, () => tojson(res));
} else {
assert.gt(greaterApplied, lesserApplied, () => tojson(res));
assert.gt(greaterDurable, lesserDurable, () => tojson(res));
}
return true;
});
}
const name = jsTestName();
const rst = new ReplSetTest({name: name, nodes: 3, settings: {chainingAllowed: false}});
rst.startSet();
rst.initiateWithHighElectionTimeout();
rst.awaitReplication();
const primary = rst.getPrimary(); // node 0
const [caughtUpSecondary, laggedSecondary] = rst.getSecondaries(); // nodes 1 and 2
const dbName = "testdb";
const collName = "testcoll";
const primaryDB = primary.getDB(dbName);
const primaryColl = primaryDB.getCollection(collName);
jsTestLog("Creating test collection");
assert.commandWorked(primaryColl.insert({"one": 1}));
rst.awaitReplication();
checkWallTimes(primary, 0 /* greater */, 1 /* lesser */);
checkWallTimes(primary, 0 /* greater */, 2 /* lesser */);
jsTestLog("Stopping replication on secondary: " + laggedSecondary.host);
stopServerReplication(laggedSecondary);
jsTestLog("Adding more documents to collection");
assert.commandWorked(primaryColl.insert({"two": 2}, {writeConcern: {w: 1}}));
rst.awaitReplication(
undefined /* timeout */, undefined /* secondaryOpTimeType */, [caughtUpSecondary]);
// Wall times of the lagged secondary should be strictly lesser.
checkWallTimes(primary, 0 /* greater */, 2 /* lesser */, true /* strict */);
checkWallTimes(primary, 1 /* greater */, 2 /* lesser */, true /* strict */);
jsTestLog("Letting lagged secondary catch up");
restartServerReplication(laggedSecondary);
rst.awaitReplication();
checkWallTimes(primary, 0 /* greater */, 1 /* lesser */);
checkWallTimes(primary, 0 /* greater */, 2 /* lesser */);
rst.stopSet();
})();
|