mongo/jstests/multiVersion/compound_hashed_shard_key.js

181 lines
8.0 KiB
JavaScript

/**
* Tests the behaviour of compound hashed shard key with different FCV versions.
*
* Compound hashed shard key creation is enabled in 4.4. In this multi version test, we ensure that
* - We cannot create compound hashed shard key on binary 4.4 in FCV 4.2 or when binary is 4.2.
* - We can create compound hashed shard key when FCV is 4.4.
* - We cannot downgrade FCV to 4.2 in the presence of a collection with compound hashed shard key.
*/
(function() {
"use strict";
load("jstests/libs/analyze_plan.js"); // For assertStagesForExplainOfCommand.
load("jstests/multiVersion/libs/multi_cluster.js"); // For upgradeCluster.
load("jstests/replsets/rslib.js"); // For awaitRSClientHosts.
TestData.skipCheckDBHashes = true; // Skip db hashes when restarting the replset.
// When checking UUID consistency, the shell attempts to run a command on the node it believes is
// primary in each shard. However, this test restarts shards, and the node that is elected primary
// after the restart may be different from the original primary. Since the shell does not retry on
// NotPrimaryErrors, and whether or not it detects the new primary before issuing the command is
// nondeterministic, skip the consistency check for this test.
TestData.skipCheckingUUIDsConsistentAcrossCluster = true;
const nodeOptions42 = {
binVersion: "last-stable"
};
const nodeOptions44 = {
binVersion: "latest"
};
const kDbName = jsTestName();
const ns = kDbName + '.coll';
// Set up a new sharded cluster consisting of 3 nodes, initially running on 4.2 binaries.
const st = new ShardingTest({
shards: 2,
rs: {nodes: 3},
other: {
mongosOptions: nodeOptions42,
configOptions: nodeOptions42,
rsOptions: nodeOptions42,
}
});
let mongosDB = st.s.getDB(kDbName);
let coll = mongosDB.coll;
coll.drop();
// Verifies that the instance is running with the specified binary version and FCV.
function assertVersionAndFCV(versions, fcv) {
const majorMinorVersion = mongosDB.version().substring(0, 3);
assert(versions.includes(majorMinorVersion));
assert.eq(assert
.commandWorked(st.rs0.getPrimary().adminCommand(
{getParameter: 1, featureCompatibilityVersion: 1}))
.featureCompatibilityVersion.version,
fcv);
assert.eq(assert
.commandWorked(st.rs1.getPrimary().adminCommand(
{getParameter: 1, featureCompatibilityVersion: 1}))
.featureCompatibilityVersion.version,
fcv);
}
// Restarts the given replset node.
function restartReplSetNode(replSet, node, options) {
const defaultOpts = {remember: true, appendOptions: true, startClean: false};
options = Object.assign(defaultOpts, (options || {}));
// Merge the new options into the existing options for the given nodes.
Object.assign(replSet.nodeOptions[`n${replSet.getNodeId(node)}`], options);
replSet.restart([node], options);
}
// Verify that the cluster is on binary version 4.2 and FCV 4.2.
assertVersionAndFCV(["4.2"], lastStableFCV);
// Cannot create a compound hashed shard key on a cluster running binary 4.2.
assert.commandWorked(st.s.adminCommand({enableSharding: kDbName}));
st.ensurePrimaryShard(kDbName, st.shard0.shardName);
assert.commandFailedWithCode(
st.s.adminCommand({shardCollection: ns, key: {a: 1, b: "hashed", c: 1}}), ErrorCodes.BadValue);
// Upgrade the cluster to the new binary version, but keep the feature compatibility version at 4.2.
st.upgradeCluster(
nodeOptions44.binVersion,
{upgradeMongos: true, upgradeShards: true, upgradeConfigs: true, waitUntilStable: true});
mongosDB = st.s.getDB(jsTestName());
coll = mongosDB.coll;
assertVersionAndFCV(["4.4", "4.3"], lastStableFCV);
// Verify that the shard key cannot be refined to a compound hashed shard key.
assert.commandWorked(st.s.adminCommand({shardCollection: kDbName + ".refine_sk", key: {a: 1}}));
assert.commandFailedWithCode(
st.s.adminCommand({refineCollectionShardKey: kDbName + ".refine_sk", key: {x: "hashed", y: 1}}),
ErrorCodes.CommandNotSupported);
// Cannot create a compound hashed shard key on binary 4.4 with FCV 4.2.
assert.commandFailedWithCode(
st.s.adminCommand({shardCollection: ns, key: {a: 1, b: "hashed", c: 1}}), ErrorCodes.BadValue);
// Can create a compound hashed shard key on binary 4.4 with FCV 4.4.
assert.commandWorked(mongosDB.adminCommand({setFeatureCompatibilityVersion: latestFCV}));
assert.commandWorked(st.s.adminCommand({shardCollection: ns, key: {a: 1, b: "hashed", c: 1}}));
// Cannot set FCV to 4.2 when there is an existing collection with compound hashed shard key.
assert.commandFailedWithCode(mongosDB.adminCommand({setFeatureCompatibilityVersion: lastStableFCV}),
31411);
// Create a collection with a compound hashed index before attempting to downgrade FCV to 4.2. We
// will subsequently test that this cannot be used to shard a collection while in FCV 4.2.
const pre42DowngradeHashedIndexColl = mongosDB.pre42DowngradeHashedIndexColl;
assert.commandWorked(
pre42DowngradeHashedIndexColl.insert([{_id: 0, a: 1, b: 1, c: 1}, {_id: 1, a: 2, b: 2}]));
assert.commandWorked(pre42DowngradeHashedIndexColl.createIndex({a: "hashed", b: 1, c: 1}));
// Can set FCV to 4.2 after dropping the collection.
coll.drop();
assert.commandWorked(mongosDB.adminCommand({setFeatureCompatibilityVersion: lastStableFCV}));
// Verify that we cannot create compound hashed shard key after downgrading to FCV 4.2, even if
// there is an existing compound hashed index.
assert.commandFailedWithCode(
st.s.adminCommand(
{shardCollection: pre42DowngradeHashedIndexColl.getFullName(), key: {a: "hashed", b: 1}}),
ErrorCodes.BadValue);
pre42DowngradeHashedIndexColl.drop();
// Set FCV back to latest and create collection with CHSK.
assert.commandWorked(mongosDB.adminCommand({setFeatureCompatibilityVersion: latestFCV}));
assert.commandWorked(st.s.adminCommand({shardCollection: ns, key: {a: 1, b: "hashed", c: 1}}));
// Set the fail point on config server to force FCV downgrade.
assert.commandWorked(st.configRS.getPrimary().getDB('admin').runCommand(
{configureFailPoint: "allowFCVDowngradeWithCompoundHashedShardKey", mode: "alwaysOn"}));
assert.commandWorked(mongosDB.adminCommand({setFeatureCompatibilityVersion: lastStableFCV}));
// CRUD operations on an existing sharded collection with compound hashed shard key works even with
// FCV 4.2.
assert.commandWorked(coll.insert([
{_id: 1, a: 2, b: 2},
{_id: 2, b: 10, c: 2},
{_id: 3, a: 1, b: 3, c: 1},
{_id: 4, a: 1, b: 4, c: 1}
]));
assert.commandWorked(coll.update({c: 2}, {$set: {p: 1}}));
assert.commandWorked(coll.remove({b: 3}));
assert.sameMembers(coll.find({a: 2, b: 2}).toArray(), [{_id: 1, a: 2, b: 2}]);
// Verify that the sharding admin commands will also work.
let configDB = st.s.getDB('config');
let lowestChunk = configDB.chunks.find({ns: ns}).sort({min: 1}).limit(1).next();
assert(lowestChunk);
assert.commandWorked(st.s.adminCommand({split: ns, bounds: [lowestChunk.min, lowestChunk.max]}));
// Find the new lowest chunk and move.
lowestChunk = configDB.chunks.find({ns: ns}).sort({min: 1}).limit(1).next();
assert.commandWorked(st.s.adminCommand(
{moveChunk: ns, bounds: [lowestChunk.min, lowestChunk.max], to: st.shard1.shardName}));
const oldMongos = st._mongos[0];
try {
// Starting mongos with 4.2 binary should fail.
st.upgradeCluster(
nodeOptions42.binVersion,
{upgradeMongos: true, upgradeShards: false, upgradeConfigs: false, waitUntilStable: true});
assert(
false,
"Upgrade to a 4.2 mongos in the presence of compound hashed shard key should not be allowed");
} catch (err) {
const newMongos = MongoRunner.runMongos(
{restart: oldMongos, binVersion: nodeOptions44.binVersion, appendOptions: true});
st["s" + 0] = st._mongos[0] = newMongos;
}
// Start mongos with the 4.4 binary for a clean shutdown.
st.upgradeCluster(nodeOptions44.binVersion,
{upgradeMongos: true, upgradeShards: false, upgradeConfigs: false});
st.stop();
}());