0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-30 17:10:48 +01:00

SERVER-42142 Add jstest confirming that a jumbo chunk that could not be split can be after calling refineCollectionShardKey

This commit is contained in:
Jamie Heppenstall 2019-07-18 14:14:26 -04:00
parent d3d8a901b7
commit 8f75d29d9c
2 changed files with 162 additions and 0 deletions

View File

@ -141,6 +141,7 @@ selector:
# Enable when 4.4 becomes last stable
- jstests/sharding/explain_exec_stats_on_shards.js
- jstests/sharding/refine_collection_shard_key_basic.js
- jstests/sharding/refine_collection_shard_key_jumbo.js
- jstests/sharding/move_primary_clone_test.js
- jstests/sharding/database_versioning_safe_secondary_reads.js
- jstests/sharding/clone_catalog_data.js

View File

@ -0,0 +1,161 @@
//
// Jumbo tests for refineCollectionShardKey.
//
(function() {
'use strict';
const st =
new ShardingTest({mongos: 1, shards: 2, other: {chunkSize: 1, enableAutoSplit: true}});
const primaryShard = st.shard0.shardName;
const secondaryShard = st.shard1.shardName;
const kDbName = 'test';
const kCollName = 'foo';
const kNsName = kDbName + '.' + kCollName;
const kConfigChunks = 'config.chunks';
const kZoneName = 'testZone';
function generateJumboChunk() {
const big = 'X'.repeat(10000);
let x = 0;
let bulk = st.s.getCollection(kNsName).initializeUnorderedBulkOp();
// Create sufficient documents to generate a jumbo chunk, and use the same shard key in all
// of them so that the chunk cannot be split and moved.
for (let i = 0; i < 500; i++) {
bulk.insert({x: x, y: i, big: big});
}
assert.writeOK(bulk.execute());
}
function runBalancer() {
st.startBalancer();
let numRounds = 0;
// Let the balancer run for 3 rounds.
assert.soon(() => {
st.awaitBalancerRound();
st.printShardingStatus(true);
numRounds++;
return (numRounds === 3);
}, 'Balancer failed to run for 3 rounds', 1000 * 60 * 10);
st.stopBalancer();
}
function validateBalancerBeforeRefine() {
runBalancer();
// Confirm that the jumbo chunk has not been split or moved from the primary shard.
const jumboChunk = st.s.getCollection(kConfigChunks).find({ns: kNsName}).toArray();
assert.eq(1, jumboChunk.length);
assert.eq(true, jumboChunk[0].jumbo);
assert.eq(primaryShard, jumboChunk[0].shard);
}
function validateBalancerAfterRefine() {
runBalancer();
// Confirm that the jumbo chunk has been split and some chunks moved to the secondary shard.
const chunks =
st.s.getCollection(kConfigChunks)
.find({ns: kNsName, min: {$lte: {x: 0, y: MaxKey}}, max: {$gt: {x: 0, y: MinKey}}})
.toArray();
assert.lt(1, chunks.length);
assert.eq(true, chunks.some((chunk) => {
return (chunk.shard === secondaryShard);
}));
}
function validateMoveChunkBeforeRefine() {
assert.commandFailedWithCode(
st.s.adminCommand({moveChunk: kNsName, find: {x: 0}, to: secondaryShard}),
ErrorCodes.ChunkTooBig);
// Confirm that the jumbo chunk has not been split or moved from the primary shard.
const jumboChunk = st.s.getCollection(kConfigChunks).find({ns: kNsName}).toArray();
assert.eq(1, jumboChunk.length);
assert.eq(primaryShard, jumboChunk[0].shard);
}
function validateMoveChunkAfterRefine() {
// Manually split the jumbo chunk before moving the smaller chunks to the secondary shard.
// We split a total of 4 times to ensure that each chunk is below the max chunk size and so
// moveChunk succeeds.
for (let i = 1; i <= 4; i++) {
assert.commandWorked(st.s.adminCommand({split: kNsName, middle: {x: 0, y: i * 125}}));
}
const chunksToMove =
st.s.getCollection(kConfigChunks)
.find({ns: kNsName, min: {$lte: {x: 0, y: MaxKey}}, max: {$gt: {x: 0, y: MinKey}}})
.toArray();
chunksToMove.forEach((chunk) => {
assert.commandWorked(st.s.adminCommand(
{moveChunk: kNsName, find: {x: 0, y: chunk.min.y}, to: secondaryShard}));
});
// Confirm that the jumbo chunk has been split and all chunks moved to the secondary shard.
const chunks =
st.s.getCollection(kConfigChunks)
.find({ns: kNsName, min: {$lte: {x: 0, y: MaxKey}}, max: {$gt: {x: 0, y: MinKey}}})
.toArray();
assert.lt(1, chunks.length);
chunks.forEach((chunk) => {
assert.eq(secondaryShard, chunk.shard);
});
}
// This test generates a jumbo chunk that cannot be split due to low shard key cardinality. It
// verifies that the balancer cannot split the chunk. After refining the shard key with
// 'refineCollectionShardKey', it verifies that the balancer can now split and move the chunk.
jsTestLog('********** BALANCER JUMBO TEST **********');
// NOTE: The current shard key is {x: 1}.
assert.commandWorked(st.s.adminCommand({enableSharding: kDbName}));
st.ensurePrimaryShard(kDbName, primaryShard);
assert.commandWorked(st.s.adminCommand({shardCollection: kNsName, key: {x: 1}}));
generateJumboChunk();
// Create a zone covering the entire range of shard keys to force the balancer to try and fail
// to move the jumbo chunk.
assert.commandWorked(st.s.adminCommand({addShardToZone: secondaryShard, zone: kZoneName}));
assert.commandWorked(st.s.adminCommand(
{updateZoneKeyRange: kNsName, min: {x: MinKey}, max: {x: MaxKey}, zone: kZoneName}));
validateBalancerBeforeRefine();
// NOTE: The shard key is now {x: 1, y: 1}.
assert.commandWorked(st.s.getCollection(kNsName).createIndex({x: 1, y: 1}));
assert.commandWorked(st.s.adminCommand({refineCollectionShardKey: kNsName, key: {x: 1, y: 1}}));
validateBalancerAfterRefine();
assert.commandWorked(st.s.getDB(kDbName).dropDatabase());
// This test generates a jumbo chunk that cannot be split due to low shard key cardinality. It
// verifies that one cannot manually move the chunk. After refining the shard key with
// 'refineCollectionShardKey', it verifies that one can now manually split and move the chunk.
jsTestLog('********** MANUAL (i.e. MOVE CHUNK) JUMBO TEST **********');
// NOTE: The current shard key is {x: 1}.
assert.commandWorked(st.s.adminCommand({enableSharding: kDbName}));
st.ensurePrimaryShard(kDbName, primaryShard);
assert.commandWorked(st.s.adminCommand({shardCollection: kNsName, key: {x: 1}}));
generateJumboChunk();
validateMoveChunkBeforeRefine();
// NOTE: The shard key is now {x: 1, y: 1}.
assert.commandWorked(st.s.getCollection(kNsName).createIndex({x: 1, y: 1}));
assert.commandWorked(st.s.adminCommand({refineCollectionShardKey: kNsName, key: {x: 1, y: 1}}));
validateMoveChunkAfterRefine();
assert.commandWorked(st.s.getDB(kDbName).dropDatabase());
st.stop();
})();