summaryrefslogtreecommitdiff
path: root/jstests/sharding/jumbo_chunks.js
blob: 519cc9fac58ed5fdd9f994f95d93d61bd36fe1a6 (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
(function() {
'use strict';

load("jstests/sharding/libs/find_chunks_util.js");

function bulkInsert(coll, keyValue, sizeMBytes) {
    const big = 'X'.repeat(1024 * 1024);  // 1MB
    var bulk = coll.initializeUnorderedBulkOp();
    for (var i = 0; i < sizeMBytes; i++) {
        bulk.insert({x: keyValue, big: big});
    }
    assert.commandWorked(bulk.execute());
}

function assertNumJumboChunks(configDB, ns, expectedNumJumboChunks) {
    assert.eq(findChunksUtil.countChunksForNs(configDB, ns, {jumbo: true}), expectedNumJumboChunks);
}

function setGlobalChunkSize(st, chunkSizeMBytes) {
    // Set global chunk size
    assert.commandWorked(
        st.s.getDB("config").settings.update({_id: 'chunksize'},
                                             {$set: {value: chunkSizeMBytes}},
                                             {upsert: true, writeConcern: {w: 'majority'}}));
}

function setCollectionChunkSize(st, ns, chunkSizeMBytes) {
    assert.commandWorked(
        st.s.adminCommand({configureCollectionBalancing: ns, chunkSize: chunkSizeMBytes}));
}

// Test setup
var st = new ShardingTest({shards: 2, other: {chunkSize: 1}});

assert.commandWorked(
    st.s.adminCommand({enablesharding: "test", primaryShard: st.shard1.shardName}));
assert.commandWorked(st.s.adminCommand({addShardToZone: st.shard0.shardName, zone: 'zoneShard0'}));

// Try to move unsuccessfully a 3MB chunk and check it gets marked as jumbo
{
    // Set the chunk range with a zone that will cause the chunk to be in the wrong place so the
    // balancer will be forced to attempt to move it out.
    assert.commandWorked(st.s.adminCommand({shardcollection: "test.foo", key: {x: 1}}));
    assert.commandWorked(st.s.adminCommand(
        {updateZoneKeyRange: 'test.foo', min: {x: 0}, max: {x: MaxKey}, zone: 'zoneShard0'}));

    var db = st.getDB("test");

    const big = 'X'.repeat(1024 * 1024);  // 1MB

    // Insert 3MB of documents to create a jumbo chunk, and use the same shard key in all of
    // them so that the chunk cannot be split.
    var bulk = db.foo.initializeUnorderedBulkOp();
    for (var i = 0; i < 3; i++) {
        bulk.insert({x: 0, big: big});
    }

    assert.commandWorked(bulk.execute());

    st.startBalancer();

    // Wait for the balancer to try to move the chunk and check it gets marked as jumbo.
    assert.soon(() => {
        let chunk = findChunksUtil.findOneChunkByNs(st.getDB('config'), 'test.foo', {min: {x: 0}});
        if (chunk == null) {
            // Balancer hasn't run and enforce the zone boundaries yet.
            return false;
        }

        assert.eq(st.shard1.shardName, chunk.shard, `${tojson(chunk)} was moved by the balancer`);
        return chunk.jumbo;
    });

    st.stopBalancer();
}

// Move successfully a 3MB chunk
// Collection chunkSize must prevail over global chunkSize setting
//     global chunkSize     -> 1MB
//     collection chunkSize -> 5MB
{
    const collName = "collA";
    const coll = st.s.getDB("test").getCollection(collName);
    const configDB = st.s.getDB("config");
    const splitPoint = 0;

    assert.commandWorked(st.s.adminCommand({shardcollection: coll.getFullName(), key: {x: 1}}));
    assert.commandWorked(st.s.adminCommand({
        updateZoneKeyRange: coll.getFullName(),
        min: {x: splitPoint},
        max: {x: MaxKey},
        zone: 'zoneShard0'
    }));

    bulkInsert(coll, splitPoint, 3);

    setCollectionChunkSize(st, coll.getFullName(), 5);
    setGlobalChunkSize(st, 1);

    // Move the 3MB chunk to shard0
    st.startBalancer();
    st.awaitCollectionBalance(coll);
    st.stopBalancer();

    const chunk =
        findChunksUtil.findOneChunkByNs(configDB, coll.getFullName(), {min: {x: splitPoint}});

    // Verify chunk has been moved to shard0
    assert.eq(st.shard0.shardName,
              chunk.shard,
              `${tojson(chunk)} was not moved to ${tojson(st.shard0.shardName)}`);
    assertNumJumboChunks(configDB, coll.getFullName(), 0);

    coll.drop();
}

// Try to move unsuccessfully a 3MB chunk and mark it as jumbo
// Collection chunkSize must prevail over global chunkSize setting
//     global chunkSize     -> 5MB
//     collection chunkSize -> 1MB
{
    const collName = "collB";
    const coll = st.s.getDB("test").getCollection(collName);
    const configDB = st.s.getDB("config");
    const splitPoint = 0;

    assert.commandWorked(st.s.adminCommand({shardcollection: coll.getFullName(), key: {x: 1}}));
    assert.commandWorked(st.s.adminCommand({
        updateZoneKeyRange: coll.getFullName(),
        min: {x: splitPoint},
        max: {x: MaxKey},
        zone: 'zoneShard0'
    }));

    bulkInsert(coll, splitPoint, 3);

    setCollectionChunkSize(st, coll.getFullName(), 1);
    setGlobalChunkSize(st, 5);

    // Try to move the 3MB chunk and mark it as jumbo
    st.startBalancer();

    assert.soon(() => {
        const chunk =
            findChunksUtil.findOneChunkByNs(configDB, coll.getFullName(), {min: {x: splitPoint}});
        if (chunk == null) {
            // Balancer hasn't run and enforce the zone boundaries yet.
            return false;
        }

        return chunk.jumbo;
    });

    st.stopBalancer();

    const chunk =
        findChunksUtil.findOneChunkByNs(configDB, coll.getFullName(), {min: {x: splitPoint}});

    // Verify chunk hasn't been moved to shard0 and it's jumbo
    assert.eq(st.shard1.shardName,
              chunk.shard,
              `${tojson(chunk)} was moved to ${tojson(st.shard0.shardName)}`);
    assertNumJumboChunks(configDB, coll.getFullName(), 1);

    coll.drop();
}

st.stop();
})();