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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
// Test that doing slaveOk reads from secondaries hits all the secondaries evenly
function testReadLoadBalancing(numReplicas) {
var s =
new ShardingTest({shards: {rs0: {nodes: numReplicas}}, verbose: 2, other: {chunkSize: 1}});
s.adminCommand({enablesharding: "test"});
s.config.settings.find().forEach(printjson);
s.adminCommand({shardcollection: "test.foo", key: {_id: 1}});
s.getDB("test").foo.insert({a: 123});
primary = s._rs[0].test.liveNodes.master;
secondaries = s._rs[0].test.liveNodes.slaves;
function rsStats() {
return s.getDB("admin").runCommand("connPoolStats")["replicaSets"][s.rs0.name];
}
assert.eq(numReplicas, rsStats().hosts.length);
function isMasterOrSecondary(info) {
if (!info.ok)
return false;
if (info.ismaster)
return true;
return info.secondary && !info.hidden;
}
assert.soon(function() {
var x = rsStats().hosts;
printjson(x);
for (var i = 0; i < x.length; i++)
if (!isMasterOrSecondary(x[i]))
return false;
return true;
});
for (var i = 0; i < secondaries.length; i++) {
assert.soon(function() {
return secondaries[i].getDB("test").foo.count() > 0;
});
secondaries[i].getDB('test').setProfilingLevel(2);
}
// Primary may change with reconfig
primary.getDB('test').setProfilingLevel(2);
// Store references to the connection so they won't be garbage collected.
var connections = [];
for (var i = 0; i < secondaries.length * 10; i++) {
conn = new Mongo(s._mongos[0].host);
conn.setSlaveOk();
conn.getDB('test').foo.findOne();
connections.push(conn);
}
var profileCriteria = {op: 'query', ns: 'test.foo'};
for (var i = 0; i < secondaries.length; i++) {
var profileCollection = secondaries[i].getDB('test').system.profile;
assert.eq(10,
profileCollection.find(profileCriteria).count(),
"Wrong number of read queries sent to secondary " + i + " " +
tojson(profileCollection.find().toArray()));
}
db = primary.getDB("test");
printjson(rs.status());
c = rs.conf();
print("config before: " + tojson(c));
for (i = 0; i < c.members.length; i++) {
if (c.members[i].host == db.runCommand("ismaster").primary)
continue;
c.members[i].hidden = true;
c.members[i].priority = 0;
break;
}
rs.reconfig(c);
print("config after: " + tojson(rs.conf()));
assert.soon(function() {
var x = rsStats();
printjson(x);
var numOk = 0;
// Now wait until the host disappears, since now we actually update our
// replica sets via isMaster in mongos
if (x.hosts.length == c["members"].length - 1)
return true;
/*
for ( var i=0; i<x.hosts.length; i++ )
if ( x.hosts[i].hidden )
return true;
*/
return false;
}, "one slave not ok", 180000, 5000);
// Secondaries may change here
secondaries = s._rs[0].test.liveNodes.slaves;
for (var i = 0; i < secondaries.length * 10; i++) {
conn = new Mongo(s._mongos[0].host);
conn.setSlaveOk();
conn.getDB('test').foo.findOne();
connections.push(conn);
}
var counts = [];
for (var i = 0; i < secondaries.length; i++) {
var profileCollection = secondaries[i].getDB('test').system.profile;
counts.push(profileCollection.find(profileCriteria).count());
}
counts = counts.sort();
assert.eq(20, Math.abs(counts[1] - counts[0]), "counts wrong: " + tojson(counts));
s.stop();
}
// for (var i = 1; i < 10; i++) {
// testReadLoadBalancing(i)
//}
// Is there a way that this can be run multiple times with different values?
// Disabled until SERVER-11956 is solved
// testReadLoadBalancing(3)
|