diff options
Diffstat (limited to 'jstests/sharding/analyze_shard_key/analyze_shard_key_database_and_shard_versioning.js')
-rw-r--r-- | jstests/sharding/analyze_shard_key/analyze_shard_key_database_and_shard_versioning.js | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/jstests/sharding/analyze_shard_key/analyze_shard_key_database_and_shard_versioning.js b/jstests/sharding/analyze_shard_key/analyze_shard_key_database_and_shard_versioning.js new file mode 100644 index 00000000000..f00c1acbad8 --- /dev/null +++ b/jstests/sharding/analyze_shard_key/analyze_shard_key_database_and_shard_versioning.js @@ -0,0 +1,101 @@ +/** + * Tests that the analyzeShardKey command uses database and shard versioning. + * + * @tags: [requires_fcv_70, featureFlagAnalyzeShardKey] + */ +(function() { +"use strict"; + +load("jstests/libs/uuid_util.js"); // for 'extractUUIDFromObject' +load("jstests/sharding/analyze_shard_key/libs/analyze_shard_key_util.js"); + +// The write concern to use when inserting documents into test collections. Waiting for the +// documents to get replicated to all nodes is necessary since the test later runs the +// analyzeShardKey command with readPreference "secondary". +const numNodesPerRS = 2; +const writeConcern = { + w: numNodesPerRS +}; + +const numMostCommonValues = 5; +const st = new ShardingTest({ + mongos: 2, + shards: 2, + rs: { + nodes: numNodesPerRS, + setParameter: { + // The calculation of the read and write distribution metrics involves generating split + // points which requires the shard key to have sufficient cardinality. To avoid needing + // to insert a lot of documents, just skip the calculation. + "failpoint.analyzeShardKeySkipCalcalutingReadWriteDistributionMetrics": + tojson({mode: "alwaysOn"}), + analyzeShardKeyNumMostCommonValues: numMostCommonValues + } + } +}); + +function runTest(readPreference) { + const dbName = "testDb" + extractUUIDFromObject(UUID()); + const collName = "testColl"; + const ns = dbName + "." + collName; + jsTest.log(`Testing analyzeShardKey with ${tojson({dbName, collName, readPreference})}`); + + // Make shard0 the primary shard. + assert.commandWorked(st.s0.adminCommand({enableSharding: dbName})); + st.ensurePrimaryShard(dbName, st.shard0.name); + + const mongos0Coll = st.s0.getCollection(ns); + assert.commandWorked(mongos0Coll.createIndex({x: 1})); + assert.commandWorked(mongos0Coll.insert([{x: -1}, {x: 1}], {writeConcern})); + + const analyzeShardKeyCmdObj = { + analyzeShardKey: ns, + key: {x: 1}, + $readPreference: readPreference + }; + const expectedMetrics = { + numDocs: 2, + isUnique: false, + numDistinctValues: 2, + mostCommonValues: [{value: {x: -1}, frequency: 1}, {value: {x: 1}, frequency: 1}], + numMostCommonValues + }; + + // Run the analyzeShardKey command and verify that the metrics are as expected. + const res0 = assert.commandWorked(st.s1.adminCommand(analyzeShardKeyCmdObj)); + AnalyzeShardKeyUtil.assertKeyCharacteristicsMetrics(res0, expectedMetrics); + + // Make shard1 the primary shard instead by running the movePrimary command against mongos0. + assert.commandWorked(st.s0.adminCommand({movePrimary: dbName, to: st.shard1.name})); + + // Rerun the analyzeShardKey command against mongos1. Since it does not know that the primary + // shard has changed, it would forward the analyzeShardKey command to shard0. Without database + // versioning, no StaleDbVersion error would be thrown and so the analyzeShardKey command would + // run on shard0 instead of on shard1. As a result, the command would fail with a + // NamespaceNotFound error. + const res1 = assert.commandWorked(st.s1.adminCommand(analyzeShardKeyCmdObj)); + AnalyzeShardKeyUtil.assertKeyCharacteristicsMetrics(res1, expectedMetrics); + + // Shard the collection and make it have two chunks: + // shard0: [MinKey, 0] + // shard1: [0, MaxKey] + // Again, run all the commands against mongos0. + assert.commandWorked(st.s0.adminCommand({shardCollection: ns, key: {x: 1}})); + assert.commandWorked(st.s0.adminCommand({split: ns, middle: {x: 0}})); + assert.commandWorked(st.s0.adminCommand( + {moveChunk: ns, find: {x: 1}, to: st.shard0.shardName, _waitForDelete: true})); + + // Rerun the analyzeShardKey command against mongos1. Since it does not know that a migration + // occurred, it would only forward the analyzeShardKey command to shard1 only. Without shard + // versioning, no StaleConfig error would be thrown and so the analyzeShardKey command would run + // only on shard1 instead of on both shard0 and shard1. As a result, the metrics would be + // incorrect. + const res2 = assert.commandWorked(st.s1.adminCommand(analyzeShardKeyCmdObj)); + AnalyzeShardKeyUtil.assertKeyCharacteristicsMetrics(res2, expectedMetrics); +} + +runTest({mode: "primary"}); +runTest({mode: "secondary"}); + +st.stop(); +})(); |