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
89
90
91
92
93
|
load("jstests/replsets/rslib.js");
(function() {
"use strict";
var name = "protocol_version_upgrade_downgrade";
var rst = new ReplSetTest({name: name, nodes: 3});
rst.startSet();
// Initiate the replset in protocol version 0.
var conf = rst.getReplSetConfig();
conf.settings = conf.settings || {};
conf.protocolVersion = 0;
// The first node will always be the primary.
conf.members[0].priority = 1;
conf.members[1].priority = 0;
conf.members[2].priority = 0;
rst.initiate(conf);
rst.awaitSecondaryNodes();
var primary = rst.getPrimary();
var primaryColl = primary.getDB("test").coll;
// Set verbosity for replication on all nodes.
var verbosity = {
"setParameter": 1,
"logComponentVerbosity": {
"replication": {"verbosity": 3},
}
};
primary.adminCommand(verbosity);
rst.getSecondaries().forEach(function(node) {
node.adminCommand(verbosity);
});
// Do a write, this will set up sync sources on secondaries.
print("do a write");
assert.writeOK(
primaryColl.bar.insert({x: 1}, {writeConcern: {w: 3, wtimeout: rst.kDefaultTimeoutMS}}));
// Check optime format in protocol version 0, which is a Timestamp.
var res = primary.adminCommand({replSetGetStatus: 1});
assert.commandWorked(res);
// Check the optime is a Timestamp, not an OpTime { ts: Timestamp, t: int }
assert.eq(res.members[0].optime.ts, null);
//
// Upgrade protocol version
//
res = primary.adminCommand({replSetGetConfig: 1});
assert.commandWorked(res);
conf = res.config;
assert.eq(conf.protocolVersion, undefined);
// Change protocol version
conf.protocolVersion = 1;
conf.version++;
reconfig(rst, conf);
// This write may block until all nodes finish upgrade, because replSetUpdatePosition may be
// rejected by the primary for mismatched config version before secondaries get reconfig.
// This will make secondaries wait for 0.5 seconds and retry.
assert.writeOK(
primaryColl.bar.insert({x: 2}, {writeConcern: {w: 3, wtimeout: rst.kDefaultTimeoutMS}}));
// Check optime format in protocol version 1, which is an object including the term.
res = primary.adminCommand({replSetGetStatus: 1});
assert.commandWorked(res);
assert.eq(res.members[0].optime.t, NumberLong(0));
// Check last vote.
var lastVote = primary.getDB("local")['replset.election'].findOne();
assert.eq(lastVote.term, NumberLong(0));
assert.eq(lastVote.candidateIndex, NumberLong(-1));
//
// Downgrade protocol version
//
res = primary.adminCommand({replSetGetConfig: 1});
assert.commandWorked(res);
conf = res.config;
assert.eq(conf.protocolVersion, 1);
// Change protocol version
conf.protocolVersion = 0;
conf.version++;
reconfig(rst, conf);
assert.writeOK(
primaryColl.bar.insert({x: 3}, {writeConcern: {w: 3, wtimeout: rst.kDefaultTimeoutMS}}));
// Check optime format in protocol version 0, which is a Timestamp.
res = primary.adminCommand({replSetGetStatus: 1});
assert.commandWorked(res);
assert.eq(res.members[0].optime.ts, null);
rst.stopSet();
})();
|