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/sharding/libs/chunk_bounds_util.js");
load("jstests/sharding/libs/find_chunks_util.js");
/**
* Asserts that the given shards have the given chunks.
*
* @param shardChunkBounds {Object} a map from each shard name to an array of the bounds for all
* the chunks on the shard. Each pair of chunk bounds is an array
* of the form [minKey, maxKey].
*/
function assertChunksOnShards(configDB, ns, shardChunkBounds) {
for (let [shardName, chunkBounds] of Object.entries(shardChunkBounds)) {
for (let bounds of chunkBounds) {
assert.eq(
shardName,
findChunksUtil.findOneChunkByNs(configDB, ns, {min: bounds[0], max: bounds[1]})
.shard,
"expected to find chunk " + tojson(bounds) + " on shard \"" + shardName + "\"");
}
}
}
/**
* Asserts that the docs are on the shards that own their corresponding chunks.
*
* @param shardChunkBounds {Object} a map from each shard name to an array of the bounds for all
* the chunks on the shard. Each pair of chunk bounds is an array
* of the form [minKey, maxKey].
* @param shardKey {Object} a map from each shard key field to 1 if the collection uses
* range based sharding and "hashed" if the collection uses
* hashed sharding. (i.e. equivalent to the value passed for the
* "key" field for the shardCollection command).
*/
function assertDocsOnShards(st, ns, shardChunkBounds, docs, shardKey) {
for (let doc of docs) {
let docShardKey = {};
for (const [k, v] of Object.entries(shardKey)) {
docShardKey[k] = (v == "hashed") ? convertShardKeyToHashed(doc[k]) : doc[k];
}
let shard = chunkBoundsUtil.findShardForShardKey(st, shardChunkBounds, docShardKey);
assert.eq(1,
shard.getCollection(ns).count(doc),
"expected to find doc " + tojson(doc) + " on shard \"" + shard.shardName + "\"");
}
}
/**
* Asserts that the given shards have the given tags.
*
* @param shardTags {Object} a map from each shard name to an array of strings representing the zone
* names that the shard owns.
*/
function assertShardTags(configDB, shardTags) {
for (let [shardName, tags] of Object.entries(shardTags)) {
assert.eq(tags.sort(),
configDB.shards.findOne({_id: shardName}).tags.sort(),
"expected shard \"" + shardName + "\" to have tags " + tojson(tags.sort()));
}
}
/**
* Adds toShard to zone and removes fromShard from zone.
*/
function moveZoneToShard(st, zoneName, fromShard, toShard) {
assert.commandWorked(st.s.adminCommand({addShardToZone: toShard.shardName, zone: zoneName}));
assert.commandWorked(
st.s.adminCommand({removeShardFromZone: fromShard.shardName, zone: zoneName}));
}
/**
* Starts the balancer, lets it run for at least the given number of rounds,
* then stops the balancer.
*/
function runBalancer(st, minNumRounds) {
st.startBalancer();
// We add 1 to the number of rounds to avoid a race condition
// where the first round is a no-op round
for (let i = 0; i < minNumRounds + 1; ++i)
st.awaitBalancerRound();
st.stopBalancer();
}
/**
* Updates the zone key range for the given namespace.
*/
function updateZoneKeyRange(st, ns, zoneName, fromRange, toRange) {
assert.commandWorked(st.s.adminCommand(
{updateZoneKeyRange: ns, min: fromRange[0], max: fromRange[1], zone: null}));
assert.commandWorked(st.s.adminCommand(
{updateZoneKeyRange: ns, min: toRange[0], max: toRange[1], zone: zoneName}));
}
|