diff options
author | Cheahuychou Mao <cheahuychou.mao@mongodb.com> | 2019-10-10 13:39:03 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-10-10 13:39:03 +0000 |
commit | 0efcbe92a9888c684472439844822e7e98885802 (patch) | |
tree | 15ed1bd224d4351fafa5b1908892c194b0d14796 | |
parent | 69ef3ed5cf4ac634fd7a749f9428871ec6f40fd2 (diff) | |
download | mongo-0efcbe92a9888c684472439844822e7e98885802.tar.gz |
SERVER-10720 Add a way for getShardVersion on mongos to return the full cached chunk distribution for a collection
-rw-r--r-- | jstests/sharding/mongos_get_shard_version.js | 101 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_get_shard_version_cmd.cpp | 25 |
2 files changed, 122 insertions, 4 deletions
diff --git a/jstests/sharding/mongos_get_shard_version.js b/jstests/sharding/mongos_get_shard_version.js new file mode 100644 index 00000000000..ecd383772e4 --- /dev/null +++ b/jstests/sharding/mongos_get_shard_version.js @@ -0,0 +1,101 @@ +/** + * Test that mongos getShardVersion returns the correct version and chunks. + */ +(function() { +'use strict'; + +const st = new ShardingTest({shards: 2, mongos: 1}); +const dbName = "test"; +const collName = "foo"; +const ns = dbName + "." + collName; +const primaryShard = st.shard0; +const otherShard = st.shard1; +const min = { + x: MinKey, + y: MinKey +}; +const max = { + x: MaxKey, + y: MaxKey +}; + +assert.commandWorked(st.s.adminCommand({enablesharding: dbName})); +st.ensurePrimaryShard(dbName, primaryShard.shardName); +assert.commandWorked(st.s.adminCommand({shardCollection: ns, key: {x: 1, y: 1}})); + +// Check shard version. +let res = st.s.adminCommand({getShardVersion: ns}); +assert.commandWorked(res); +assert.eq(res.version.t, 1); +assert.eq(res.version.i, 0); +assert.eq(undefined, res.chunks); + +// When fullMetadata set to true, chunks should be included in the response +// if the mongos version is v4.4. +res = st.s.adminCommand({getShardVersion: ns, fullMetadata: true}); +assert.commandWorked(res); +assert.eq(res.version.t, 1); +assert.eq(res.version.i, 0); +if (jsTestOptions().mongosBinVersion == "last-stable") { + assert.eq(undefined, res.chunks); +} else { + assert.eq(1, res.chunks.length); + assert.eq(min, res.chunks[0][0]); + assert.eq(max, res.chunks[0][1]); +} + +// Split the existing chunks to create a large number of chunks (> 16MB). +// This needs to be done twice since the BSONObj size limit also applies +// to command objects for commands like splitChunk. + +// The chunk min and max need to be large, otherwise we need a lot more +// chunks to reach the size limit. +const splitPoint = { + x: 0, + y: "A".repeat(512) +}; + +let splitPoints = []; +for (let i = 0; i < 10000; i++) { + splitPoints.push({x: i, y: splitPoint.y}); +} +assert.commandWorked(st.rs0.getPrimary().getDB('admin').runCommand({ + splitChunk: ns, + from: st.shard0.shardName, + min: min, + max: max, + keyPattern: {x: 1}, + splitKeys: splitPoints, + epoch: res.versionEpoch, +})); + +let prevMin = splitPoints[splitPoints.length - 1]; +splitPoints = []; +for (let i = 10000; i < 20000; i++) { + splitPoints.push({x: i, y: splitPoint.y}); +} +assert.commandWorked(st.rs0.getPrimary().getDB('admin').runCommand({ + splitChunk: ns, + from: st.shard0.shardName, + min: prevMin, + max: max, + keyPattern: {x: 1}, + splitKeys: splitPoints, + epoch: res.versionEpoch, +})); + +// Move a chunk so that mongos's routing entry gets marked as stale, making +// the next getShardVersion trigger a refresh. +assert.commandWorked( + st.s.adminCommand({moveChunk: ns, find: splitPoint, to: otherShard.shardName})); + +// Chunks should not be included in the response regardless of the mongos version +// because the chunk size exceeds the limit. +res = st.s.adminCommand({getShardVersion: ns, fullMetadata: true}); +assert.commandWorked(res); +assert.eq(res.version.t, 4); +assert.eq(res.version.i, 1); +assert.eq(undefined, res.chunks); + +st.stop(); +})(); diff --git a/src/mongo/s/commands/cluster_get_shard_version_cmd.cpp b/src/mongo/s/commands/cluster_get_shard_version_cmd.cpp index 48f090d10ee..78b3021a698 100644 --- a/src/mongo/s/commands/cluster_get_shard_version_cmd.cpp +++ b/src/mongo/s/commands/cluster_get_shard_version_cmd.cpp @@ -107,12 +107,29 @@ public: str::stream() << "Collection " << nss.ns() << " is not sharded.", cachedCollInfo.cm()); const auto cm = cachedCollInfo.cm(); + cm->getVersion().appendLegacyWithField(&result, "version"); - for (const auto& chunk : cm->chunks()) { - log() << redact(chunk.toString()); + if (cmdObj["fullMetadata"].trueValue()) { + BSONArrayBuilder chunksArrBuilder; + bool exceedsSizeLimit = false; + + for (const auto& chunk : cm->chunks()) { + log() << redact(chunk.toString()); + if (!exceedsSizeLimit) { + BSONArrayBuilder chunkBB(chunksArrBuilder.subarrayStart()); + chunkBB.append(chunk.getMin()); + chunkBB.append(chunk.getMax()); + chunkBB.done(); + if (chunksArrBuilder.len() + result.len() > BSONObjMaxUserSize) { + exceedsSizeLimit = true; + } + } + } + + if (!exceedsSizeLimit) { + result.append("chunks", chunksArrBuilder.arr()); + } } - - cm->getVersion().appendLegacyWithField(&result, "version"); } return true; |