summaryrefslogtreecommitdiff
path: root/jstests/slowNightly/replReads.js
blob: dadc2c6cac736806829edfedab65757611733ee0 (plain)
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
2// Test that doing slaveOk reads from secondaries hits all the secondaries evenly

function testReadLoadBalancing(numReplicas) {

    s = new ShardingTest( "replReads" , 1 /* numShards */, 0 /* verboseLevel */, 1 /* numMongos */, { rs : true , numReplicas : numReplicas, 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"]["replReads-rs0"];
    }
    
    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)

    for (var i = 0; i < secondaries.length * 10; i++) {
        conn = new Mongo(s._mongos[0].host)
        conn.setSlaveOk()
        conn.getDB('test').foo.findOne()
    }

    for (var i = 0; i < secondaries.length; i++) {
        var profileCollection = secondaries[i].getDB('test').system.profile;
        assert.eq(10, profileCollection.find().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 == rs.conf()["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()
    }

    var counts = []
    for (var i = 0; i < secondaries.length; i++) {
        var profileCollection = secondaries[i].getDB('test').system.profile;
        counts.push( profileCollection.find().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?
testReadLoadBalancing(3)