summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Boros <matt.boros@mongodb.com>2023-01-06 21:55:11 +0000
committerMatt Boros <matt.boros@mongodb.com>2023-01-06 21:55:11 +0000
commitf1af163bcde78896b83ee5115eb8545e086b5c49 (patch)
tree09161f3de3ee91c3afb08849f44b8d380d655691
parent26c01ac79efc0708cb2795b42f802c0cea8a10f5 (diff)
downloadmongo-f1af163bcde78896b83ee5115eb8545e086b5c49.tar.gz
remove fcv startup check, add downgrade check
-rw-r--r--jstests/multiVersion/partial_index_fcv.js38
-rw-r--r--src/mongo/db/catalog/index_catalog_impl.cpp9
-rw-r--r--src/mongo/db/commands/set_feature_compatibility_version_command.cpp37
3 files changed, 80 insertions, 4 deletions
diff --git a/jstests/multiVersion/partial_index_fcv.js b/jstests/multiVersion/partial_index_fcv.js
new file mode 100644
index 00000000000..b2cd76d0cd4
--- /dev/null
+++ b/jstests/multiVersion/partial_index_fcv.js
@@ -0,0 +1,38 @@
+/**
+ *
+ */
+
+(function() {
+// 'use strict';
+
+const dbpath = MongoRunner.dataPath + 'partial_index_fcv';
+resetDbpath(dbpath);
+
+let conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: '6.0', noCleanData: true});
+
+db = conn.getDB('test');
+coll = db['partial_index_fcv'];
+assert.commandWorked(coll.createIndex(
+ {a: 1, b: 1}, {partialFilterExpression: {$or: [{a: {$lt: 20}}, {b: {$lt: 10}}]}}))
+
+coll.insert({a: 1, b: 1})
+coll.insert({a: 5, b: 6})
+coll.insert({a: 1, b: 20})
+coll.insert({a: 30, b: 1})
+coll.insert({a: 30, b: 20})
+
+assert.commandFailedWithCode(db.adminCommand({setFeatureCompatibilityVersion: '5.0'}),
+ ErrorCodes.CannotDowngrade);
+coll.dropIndexes();
+assert.commandWorked(db.adminCommand({setFeatureCompatibilityVersion: '5.0'}));
+
+MongoRunner.stopMongod(conn);
+
+conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: '5.0', noCleanData: true});
+
+db = conn.getDB('test');
+coll = db['partial_index_fcv'];
+assert.eq(coll.aggregate().toArray().length, 5);
+
+MongoRunner.stopMongod(conn);
+})(); \ No newline at end of file
diff --git a/src/mongo/db/catalog/index_catalog_impl.cpp b/src/mongo/db/catalog/index_catalog_impl.cpp
index 6be0b560bf9..f99fcb3e4a2 100644
--- a/src/mongo/db/catalog/index_catalog_impl.cpp
+++ b/src/mongo/db/catalog/index_catalog_impl.cpp
@@ -890,10 +890,11 @@ Status IndexCatalogImpl::_isSpecOk(OperationContext* opCtx,
}
const std::unique_ptr<MatchExpression> filterExpr = std::move(statusWithMatcher.getValue());
- Status status =
- _checkValidFilterExpressions(filterExpr.get(),
- feature_flags::gTimeseriesMetricIndexes.isEnabled(
- serverGlobalParams.featureCompatibility));
+ Status status = _checkValidFilterExpressions(
+ filterExpr.get(),
+ serverGlobalParams.featureCompatibility.isVersionInitialized() &&
+ feature_flags::gTimeseriesMetricIndexes.isEnabled(
+ serverGlobalParams.featureCompatibility));
if (!status.isOK()) {
return status;
}
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 0c8f5a42c99..15c10444a72 100644
--- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
+++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
@@ -84,6 +84,7 @@
#include "mongo/db/session_catalog.h"
#include "mongo/db/session_catalog_mongod.h"
#include "mongo/db/session_txn_record_gen.h"
+#include "mongo/db/storage/storage_parameters_gen.h"
#include "mongo/db/timeseries/timeseries_index_schema_conversion_functions.h"
#include "mongo/db/vector_clock.h"
#include "mongo/idl/cluster_server_parameter_gen.h"
@@ -831,6 +832,42 @@ private:
}
}
+ if (!feature_flags::gTimeseriesMetricIndexes.isEnabledOnVersion(requestedVersion)) {
+ 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, /*includeUnfinishedIndexes=*/true);
+
+ while (indexIt->more()) {
+ auto indexEntry = indexIt->next();
+
+ if (auto filter = indexEntry->getFilterExpression()) {
+ auto status = IndexCatalogImpl::checkValidFilterExpressions(
+ filter,
+ /*timeseriesMetricIndexesFeatureFlagEnabled*/ false);
+ uassert(ErrorCodes::CannotDowngrade,
+ str::stream()
+ << "Cannot downgrade the cluster when there are "
+ "secondary indexes with partial filter expressions "
+ "that contain $in/$or/$geoWithin or an $and that is "
+ "not top level. Drop all indexes containing these "
+ "partial filter elements before downgrading. First "
+ "detected incompatible index name: '"
+ << indexEntry->descriptor()->indexName()
+ << "' on collection: '" << collection->ns().coll()
+ << "'",
+ status.isOK());
+ }
+ }
+ return true;
+ });
+ }
+ }
+
if (serverGlobalParams.featureCompatibility
.isFCVDowngradingOrAlreadyDowngradedFromLatest()) {
for (const auto& tenantDbName : DatabaseHolder::get(opCtx)->getNames()) {