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
129
|
// 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)
|