diff options
4 files changed, 80 insertions, 106 deletions
diff --git a/jstests/multiVersion/partial_index_fcv.js b/jstests/multiVersion/partial_index_fcv.js deleted file mode 100644 index b2cd76d0cd4..00000000000 --- a/jstests/multiVersion/partial_index_fcv.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * - */ - -(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/jstests/multiVersion/targetedTestsLastLtsFeatures/partial_indexes_downgrade.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/partial_indexes_downgrade.js new file mode 100644 index 00000000000..5b3101a5121 --- /dev/null +++ b/jstests/multiVersion/targetedTestsLastLtsFeatures/partial_indexes_downgrade.js @@ -0,0 +1,50 @@ +/** + * Tests that we cannot downgrade FCV when we have partial indexes with $or/$in/$geoWithin. + */ + +(function() { +'use strict'; + +const dbpath = MongoRunner.dataPath + 'partial_indexes_downgrade'; + +function runTest(targetFCV) { + resetDbpath(dbpath); + + // Start with 6.0, create a partial index with an $or, then make sure we fail to downgrade FCV + // to 5.x. Drop the index, then actually downgrade to 5.x. + { + const conn = + MongoRunner.runMongod({dbpath: dbpath, binVersion: 'latest', noCleanData: true}); + + const db = conn.getDB('test'); + const coll = db['partial_indexes_downgrade']; + 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: 30, b: 20}); + + assert.commandFailedWithCode(db.adminCommand({setFeatureCompatibilityVersion: targetFCV}), + ErrorCodes.CannotDowngrade); + coll.dropIndexes(); + assert.commandWorked(db.adminCommand({setFeatureCompatibilityVersion: targetFCV})); + + MongoRunner.stopMongod(conn); + } + + // Startup with 5.x binary, with FCV set to 5.x. + { + const conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: '5.0', noCleanData: true}); + + const db = conn.getDB('test'); + const coll = db['partial_indexes_downgrade']; + // Make sure we are on the same db path as before. + assert.eq(coll.aggregate().toArray().length, 2); + + MongoRunner.stopMongod(conn); + } +} + +runTest(lastLTSFCV); +runTest(lastContinuousFCV); +})();
\ 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 f99fcb3e4a2..8f2a3c5e308 100644 --- a/src/mongo/db/catalog/index_catalog_impl.cpp +++ b/src/mongo/db/catalog/index_catalog_impl.cpp @@ -674,13 +674,7 @@ Status _checkValidFilterExpressions(const MatchExpression* expression, } } return Status::OK(); - case MatchExpression::GEO: case MatchExpression::INTERNAL_BUCKET_GEO_WITHIN: - case MatchExpression::INTERNAL_EXPR_EQ: - case MatchExpression::INTERNAL_EXPR_LT: - case MatchExpression::INTERNAL_EXPR_LTE: - case MatchExpression::INTERNAL_EXPR_GT: - case MatchExpression::INTERNAL_EXPR_GTE: case MatchExpression::MATCH_IN: if (timeseriesMetricIndexesFeatureFlagEnabled) { return Status::OK(); @@ -694,6 +688,12 @@ Status _checkValidFilterExpressions(const MatchExpression* expression, case MatchExpression::GT: case MatchExpression::GTE: case MatchExpression::EXISTS: + case MatchExpression::INTERNAL_EXPR_EQ: + case MatchExpression::INTERNAL_EXPR_LT: + case MatchExpression::INTERNAL_EXPR_LTE: + case MatchExpression::INTERNAL_EXPR_GT: + case MatchExpression::INTERNAL_EXPR_GTE: + case MatchExpression::GEO: case MatchExpression::TYPE_OPERATOR: return Status::OK(); default: 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 15c10444a72..bb73916d87f 100644 --- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp +++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp @@ -746,17 +746,12 @@ private: // (Generic FCV reference): TODO SERVER-60912: When kLastLTS is 6.0, remove this FCV-gated // downgrade code. - if (requestedVersion == multiversion::GenericFCV::kLastLTS) { + 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) { - invariant(collection->getTimeseriesOptions()); - + opCtx, tenantDbName, MODE_X, [&](const CollectionPtr& collection) { auto indexCatalog = collection->getIndexCatalog(); auto indexIt = indexCatalog->getIndexIterator( opCtx, /*includeUnfinishedIndexes=*/true); @@ -767,20 +762,26 @@ private: // in 5.2 and up. If the user tries to downgrade the cluster to an // earlier version, they must first remove all incompatible secondary // indexes on time-series measurements. - uassert( - ErrorCodes::CannotDowngrade, - str::stream() - << "Cannot downgrade the cluster when there are secondary " - "indexes on time-series measurements present, or when there " - "are partial indexes on a time-series collection. Drop all " - "secondary indexes on time-series measurements, and all " - "partial indexes on time-series collections, before " - "downgrading. First detected incompatible index name: '" - << indexEntry->descriptor()->indexName() << "' on collection: '" - << collection->ns().getTimeseriesViewNamespace() << "'", - timeseries::isBucketsIndexSpecCompatibleForDowngrade( - *collection->getTimeseriesOptions(), - indexEntry->descriptor()->infoObj())); + if (requestedVersion == multiversion::GenericFCV::kLastLTS && + collection->getTimeseriesOptions()) { + uassert( + ErrorCodes::CannotDowngrade, + str::stream() + << "Cannot downgrade the cluster when there are secondary " + "indexes on time-series measurements present, or when " + "there " + "are partial indexes on a time-series collection. Drop " + "all " + "secondary indexes on time-series measurements, and all " + "partial indexes on time-series collections, before " + "downgrading. First detected incompatible index name: '" + << indexEntry->descriptor()->indexName() + << "' on collection: '" + << collection->ns().getTimeseriesViewNamespace() << "'", + timeseries::isBucketsIndexSpecCompatibleForDowngrade( + *collection->getTimeseriesOptions(), + indexEntry->descriptor()->infoObj())); + } if (auto filter = indexEntry->getFilterExpression()) { auto status = IndexCatalogImpl::checkValidFilterExpressions( @@ -795,8 +796,8 @@ private: "partial filter elements before downgrading. First " "detected incompatible index name: '" << indexEntry->descriptor()->indexName() - << "' on collection: '" - << collection->ns().getTimeseriesViewNamespace() << "'", + << "' on collection: '" << collection->ns().coll() + << "'", status.isOK()); } } @@ -825,45 +826,6 @@ private: } return true; - }, - [&](const CollectionPtr& collection) { - return collection->getTimeseriesOptions() != boost::none; - }); - } - } - - 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; }); } } |