summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuhong Zhang <yuhong.zhang@mongodb.com>2022-02-15 20:08:19 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-02-15 21:11:33 +0000
commitad5977c28ad442c22e9b4a9b2c7198fd3129f046 (patch)
treedc2a6886a6d3ecbc7c85c980b8767164dd67544f
parente840bb65779035e3f5e7d1fb9b6951c291957a74 (diff)
downloadmongo-r6.0.0-alpha.tar.gz
SERVER-63501 Disallow downgrade when the index `disallowNewDuplicateKeys` field existsr6.0.0-alpha
-rw-r--r--jstests/noPassthrough/index_disallowNewDuplicateKeys_downgrade.js66
-rw-r--r--src/mongo/db/commands/set_feature_compatibility_version_command.cpp30
2 files changed, 96 insertions, 0 deletions
diff --git a/jstests/noPassthrough/index_disallowNewDuplicateKeys_downgrade.js b/jstests/noPassthrough/index_disallowNewDuplicateKeys_downgrade.js
new file mode 100644
index 00000000000..4c733772788
--- /dev/null
+++ b/jstests/noPassthrough/index_disallowNewDuplicateKeys_downgrade.js
@@ -0,0 +1,66 @@
+/**
+ * Tests that the cluster cannot be downgraded when there are indexes with the
+ * 'disallowNewDuplicateKeys' field present.
+ *
+ * TODO SERVER-63563: Update this test once kLastContinuous is 5.3.
+ * TODO SERVER-63564: Remove this test once kLastLTS is 6.0.
+ *
+ * @tags: [requires_fcv_53]
+ */
+(function() {
+"use strict";
+
+const conn = MongoRunner.runMongod();
+const db = conn.getDB("test");
+
+const collModIndexUniqueEnabled = assert
+ .commandWorked(db.getMongo().adminCommand(
+ {getParameter: 1, featureFlagCollModIndexUnique: 1}))
+ .featureFlagCollModIndexUnique.value;
+
+if (!collModIndexUniqueEnabled) {
+ jsTestLog('Skipping test because the collMod unique index feature flag is disabled.');
+ MongoRunner.stopMongod(conn);
+ return;
+}
+
+const collName = "index_disallowNewDuplicateKeys_downgrade";
+const coll = db.getCollection(collName);
+assert.commandWorked(db.createCollection(coll.getName()));
+
+function checkIndexForDowngrade(withFCV, fixIndex, isCompatible) {
+ assert.commandWorked(coll.createIndex({a: 1}, {disallowNewDuplicateKeys: true}));
+ assert.commandWorked(coll.createIndex({b: 1}, {disallowNewDuplicateKeys: true}));
+
+ if (fixIndex) {
+ // Resolves the incompatibility before the downgrade.
+ assert.commandWorked(coll.dropIndex({a: 1}));
+ assert.commandWorked(db.runCommand(
+ {collMod: collName, index: {keyPattern: {b: 1}, disallowNewDuplicateKeys: false}}));
+ } else if (!isCompatible) {
+ assert.commandFailedWithCode(db.adminCommand({setFeatureCompatibilityVersion: withFCV}),
+ ErrorCodes.CannotDowngrade);
+ assert.commandWorked(coll.dropIndexes("*"));
+ }
+
+ // Downgrades to the version 'withFCV' and reset to 'latestFCV'.
+ assert.commandWorked(db.adminCommand({setFeatureCompatibilityVersion: withFCV}));
+ assert.commandWorked(db.adminCommand({setFeatureCompatibilityVersion: latestFCV}));
+
+ assert.commandWorked(coll.dropIndexes("*"));
+}
+
+// Fails to downgrade to 5.2.
+checkIndexForDowngrade(lastContinuousFCV, false, false);
+
+// Fails to downgrade to 5.0.
+checkIndexForDowngrade(lastLTSFCV, false, false);
+
+// Successfully downgrades to 5.2 after removing the 'disallowNewDuplicateKeys' field.
+checkIndexForDowngrade(lastContinuousFCV, true, true);
+
+// Successfully downgrades to 5.0 after removing the 'disallowNewDuplicateKeys' field.
+checkIndexForDowngrade(lastLTSFCV, true, true);
+
+MongoRunner.stopMongod(conn);
+}()); \ No newline at end of file
diff --git a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
index f07008508d8..5ceb71ed310 100644
--- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
+++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
@@ -719,6 +719,36 @@ private:
});
}
+ // TODO SERVER-63563: Only check on last-lts when FCV 5.3 becomes last-continuous.
+ // TODO SERVER-63564: Remove once FCV 6.0 becomes last-lts.
+ for (const auto& tenantDbName : DatabaseHolder::get(opCtx)->getNames()) {
+ const auto& dbName = tenantDbName.dbName();
+ Lock::DBLock dbLock(opCtx, dbName, MODE_IX);
+ catalog::forEachCollectionFromDb(
+ opCtx, tenantDbName, MODE_X, [&](const CollectionPtr& collection) {
+ auto indexCatalog = collection->getIndexCatalog();
+ auto indexIt = indexCatalog->getIndexIterator(
+ opCtx, true /* includeUnfinishedIndexes */);
+ while (indexIt->more()) {
+ auto indexEntry = indexIt->next();
+ uassert(
+ ErrorCodes::CannotDowngrade,
+ fmt::format(
+ "Cannot downgrade the cluster when there are indexes that have "
+ "the 'disallowNewDuplicateKeys' field. Use listIndexes to find "
+ "them and drop "
+ "the indexes or use collMod to manually set it to false to "
+ "remove the field "
+ "before downgrading. First detected incompatible index name: "
+ "'{}' on collection: '{}'",
+ indexEntry->descriptor()->indexName(),
+ collection->ns().toString()),
+ !indexEntry->descriptor()->disallowNewDuplicateKeys());
+ }
+ return true;
+ });
+ }
+
// Drop the pre-images collection if 'changeStreamPreAndPostImages' feature flag is not
// enabled on the downgrade version.
// TODO SERVER-61770: Remove once FCV 6.0 becomes last-lts.