diff options
Diffstat (limited to 'src/mongo/db/catalog/coll_mod.cpp')
| -rw-r--r-- | src/mongo/db/catalog/coll_mod.cpp | 170 |
1 files changed, 30 insertions, 140 deletions
diff --git a/src/mongo/db/catalog/coll_mod.cpp b/src/mongo/db/catalog/coll_mod.cpp index 2c9f03053d0..8af0ba8efc9 100644 --- a/src/mongo/db/catalog/coll_mod.cpp +++ b/src/mongo/db/catalog/coll_mod.cpp @@ -33,7 +33,6 @@ #include "mongo/db/catalog/coll_mod.h" -#include "mongo/db/stats/counters.h" #include <boost/optional.hpp> #include <memory> @@ -45,7 +44,7 @@ #include "mongo/db/catalog/index_catalog.h" #include "mongo/db/catalog/index_key_validate.h" #include "mongo/db/coll_mod_gen.h" -#include "mongo/db/concurrency/exception_util.h" +#include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/curop_failpoint_helpers.h" #include "mongo/db/db_raii.h" #include "mongo/db/index/index_descriptor.h" @@ -54,7 +53,6 @@ #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/s/collection_sharding_state.h" #include "mongo/db/s/database_sharding_state.h" -#include "mongo/db/s/shard_key_index_util.h" #include "mongo/db/server_options.h" #include "mongo/db/service_context.h" #include "mongo/db/storage/recovery_unit.h" @@ -64,7 +62,6 @@ #include "mongo/db/views/view_catalog_helpers.h" #include "mongo/idl/command_generic_argument.h" #include "mongo/logv2/log.h" -#include "mongo/s/grid.h" #include "mongo/util/fail_point.h" #include "mongo/util/version/releases.h" #include "mongo/util/visit_helper.h" @@ -112,13 +109,12 @@ struct ParsedCollModRequest { boost::optional<Collection::Validator> collValidator; boost::optional<ValidationActionEnum> collValidationAction; boost::optional<ValidationLevelEnum> collValidationLevel; - boost::optional<bool> recordPreImages; + bool recordPreImages = false; boost::optional<ChangeStreamPreAndPostImagesOptions> changeStreamPreAndPostImagesOptions; int numModifications = 0; bool dryRun = false; boost::optional<long long> cappedSize; boost::optional<long long> cappedMax; - boost::optional<bool> timeseriesBucketsMayHaveMixedSchemaData; }; Status getNotSupportedOnViewError(StringData fieldName) { @@ -254,8 +250,7 @@ StatusWith<std::pair<ParsedCollModRequest, BSONObj>> parseCollModRequest(Operati "TTL indexes are not supported for capped collections."}; } if (auto status = index_key_validate::validateExpireAfterSeconds( - *cmdIndex.getExpireAfterSeconds(), - index_key_validate::ValidateExpireAfterSecondsMode::kSecondaryTTLIndex); + *cmdIndex.getExpireAfterSeconds()); !status.isOK()) { return {ErrorCodes::InvalidOptions, status.reason()}; } @@ -289,8 +284,7 @@ StatusWith<std::pair<ParsedCollModRequest, BSONObj>> parseCollModRequest(Operati } } else { std::vector<const IndexDescriptor*> indexes; - coll->getIndexCatalog()->findIndexesByKeyPattern( - opCtx, keyPattern, IndexCatalog::InclusionPolicy::kReady, &indexes); + coll->getIndexCatalog()->findIndexesByKeyPattern(opCtx, keyPattern, false, &indexes); if (indexes.size() > 1) { return {ErrorCodes::AmbiguousIndexKeyPattern, @@ -343,7 +337,7 @@ StatusWith<std::pair<ParsedCollModRequest, BSONObj>> parseCollModRequest(Operati if (cmrIndex->idx->unique()) { indexForOplog->setUnique(boost::none); } else { - // Disallow one-step unique conversion. The user has to set + // Disallow one-step unique convertion. The user has to set // 'prepareUnique' to true first. if (!cmrIndex->idx->prepareUnique()) { return Status(ErrorCodes::InvalidOptions, @@ -369,29 +363,6 @@ StatusWith<std::pair<ParsedCollModRequest, BSONObj>> parseCollModRequest(Operati return {ErrorCodes::BadValue, "can't hide _id index"}; } - // If the index is not hidden and we are trying to hide it, check if it is possible - // to drop the shard key index, so it could be possible to hide it. - if (!cmrIndex->idx->hidden() && *cmdIndex.getHidden()) { - if (auto catalogClient = Grid::get(opCtx)->catalogClient()) { - try { - auto shardedColl = catalogClient->getCollection(opCtx, nss); - - if (isLastNonHiddenRangedShardKeyIndex( - opCtx, - coll, - coll->getIndexCatalog(), - cmrIndex->idx->indexName(), - shardedColl.getKeyPattern().toBSON())) { - return {ErrorCodes::InvalidOptions, - "Can't hide the only compatible index for this collection's " - "shard key"}; - } - } catch (ExceptionFor<ErrorCodes::NamespaceNotFound>&) { - // The collection is unsharded or doesn't exist. - } - } - } - // Hiding a hidden index or unhiding a visible index should be treated as a no-op. if (cmrIndex->idx->hidden() == *cmdIndex.getHidden()) { indexForOplog->setHidden(boost::none); @@ -401,35 +372,12 @@ StatusWith<std::pair<ParsedCollModRequest, BSONObj>> parseCollModRequest(Operati } if (cmdIndex.getPrepareUnique()) { - // Check if prepareUnique is being set on a time-series collection. - if (isTimeseries) { - return {ErrorCodes::InvalidOptions, - "cannot set 'prepareUnique' for indexes of a time-series collection."}; - } parsed.numModifications++; // Attempting to modify with the same value should be treated as a no-op. if (cmrIndex->idx->prepareUnique() == *cmdIndex.getPrepareUnique() || cmrIndex->idx->unique()) { indexForOplog->setPrepareUnique(boost::none); } else { - // Checks if the index key pattern conflicts with the shard key pattern. - if (auto catalogClient = Grid::get(opCtx)->catalogClient()) { - try { - auto shardedColl = catalogClient->getCollection(opCtx, nss); - const ShardKeyPattern shardKeyPattern(shardedColl.getKeyPattern()); - if (!shardKeyPattern.isIndexUniquenessCompatible( - cmrIndex->idx->keyPattern())) { - return {ErrorCodes::InvalidOptions, - fmt::format( - "cannot set 'prepareUnique' for index {} with shard key " - "pattern {}", - cmrIndex->idx->keyPattern().toString(), - shardKeyPattern.toBSON().toString())}; - } - } catch (ExceptionFor<ErrorCodes::NamespaceNotFound>&) { - // The collection is unsharded or doesn't exist. - } - } cmrIndex->indexPrepareUnique = cmdIndex.getPrepareUnique(); } } @@ -482,11 +430,6 @@ StatusWith<std::pair<ParsedCollModRequest, BSONObj>> parseCollModRequest(Operati validatorObj.getOwned(), MatchExpressionParser::kDefaultSpecialFeatures, maxFeatureCompatibilityVersion); - - // Increment counters to track the usage of schema validators. - validatorCounters.incrementCounters( - cmd.kCommandName, parsed.collValidator->validatorDoc, parsed.collValidator->isOK()); - if (!parsed.collValidator->isOK()) { return parsed.collValidator->getStatus(); } @@ -590,9 +533,7 @@ StatusWith<std::pair<ParsedCollModRequest, BSONObj>> parseCollModRequest(Operati }, [&oplogEntryBuilder](std::int64_t value) { oplogEntryBuilder.append(CollMod::kExpireAfterSecondsFieldName, value); - return index_key_validate::validateExpireAfterSeconds( - value, - index_key_validate::ValidateExpireAfterSecondsMode::kClusteredTTLIndex); + return index_key_validate::validateExpireAfterSeconds(value); }, }, *expireAfterSeconds); @@ -611,17 +552,6 @@ StatusWith<std::pair<ParsedCollModRequest, BSONObj>> parseCollModRequest(Operati timeseries->serialize(&subObjBuilder); } - if (auto mixedSchema = cmr.getTimeseriesBucketsMayHaveMixedSchemaData()) { - if (!isTimeseries) { - return getOnlySupportedOnTimeseriesError( - CollMod::kTimeseriesBucketsMayHaveMixedSchemaDataFieldName); - } - - parsed.timeseriesBucketsMayHaveMixedSchemaData = mixedSchema; - oplogEntryBuilder.append(CollMod::kTimeseriesBucketsMayHaveMixedSchemaDataFieldName, - *mixedSchema); - } - if (auto& dryRun = cmr.getDryRun()) { parsed.dryRun = *dryRun; // The dry run option should never be included in a collMod oplog entry. @@ -666,8 +596,7 @@ void _setClusteredExpireAfterSeconds( if (!oldExpireAfterSeconds) { auto ttlCache = &TTLCollectionCache::get(opCtx->getServiceContext()); opCtx->recoveryUnit()->onCommit([ttlCache, uuid = coll->uuid()](auto _) { - ttlCache->registerTTLInfo( - uuid, TTLCollectionCache::Info{TTLCollectionCache::ClusteredId{}}); + ttlCache->registerTTLInfo(uuid, TTLCollectionCache::ClusteredId()); }); } @@ -917,7 +846,7 @@ Status _collModInternal(OperationContext* opCtx, cmrNew.recordPreImages = false; } - if (cmrNew.recordPreImages && *cmrNew.recordPreImages) { + if (cmrNew.recordPreImages) { cmrNew.changeStreamPreAndPostImagesOptions = ChangeStreamPreAndPostImagesOptions(false); } @@ -947,11 +876,6 @@ Status _collModInternal(OperationContext* opCtx, *cmd.getExpireAfterSeconds()); } - if (auto mixedSchema = cmrNew.timeseriesBucketsMayHaveMixedSchemaData) { - coll.getWritableCollection(opCtx)->setTimeseriesBucketsMayHaveMixedSchemaData( - opCtx, mixedSchema); - } - // Handle index modifications. processCollModIndexRequest( opCtx, &coll, cmrNew.indexRequest, &indexCollModInfo, result, mode); @@ -969,9 +893,8 @@ Status _collModInternal(OperationContext* opCtx, "Failed to set validationLevel"); } - if (cmrNew.recordPreImages.has_value() && - *cmrNew.recordPreImages != oldCollOptions.recordPreImages) { - coll.getWritableCollection(opCtx)->setRecordPreImages(opCtx, *cmrNew.recordPreImages); + if (cmrNew.recordPreImages != oldCollOptions.recordPreImages) { + coll.getWritableCollection(opCtx)->setRecordPreImages(opCtx, cmrNew.recordPreImages); } if (cmrNew.changeStreamPreAndPostImagesOptions.has_value() && @@ -991,9 +914,9 @@ Status _collModInternal(OperationContext* opCtx, } } - // Fix any invalid index options for indexes belonging to this collection. + // Remove any invalid index options for indexes belonging to this collection. std::vector<std::string> indexesWithInvalidOptions = - coll.getWritableCollection(opCtx)->repairInvalidIndexOptions(opCtx); + coll.getWritableCollection(opCtx)->removeInvalidIndexOptions(opCtx); for (const auto& indexWithInvalidOptions : indexesWithInvalidOptions) { const IndexDescriptor* desc = coll->getIndexCatalog()->findIndexByName(opCtx, indexWithInvalidOptions); @@ -1007,24 +930,24 @@ Status _collModInternal(OperationContext* opCtx, // (Generic FCV reference): TODO SERVER-60912: When kLastLTS is 6.0, remove this FCV-gated // upgrade/downgrade code. const auto currentVersion = serverGlobalParams.featureCompatibility.getVersion(); - if (coll->getTimeseriesOptions()) { - if (currentVersion == multiversion::GenericFCV::kUpgradingFromLastLTSToLatest) { - // (Generic FCV reference): While upgrading the FCV from kLastLTS to kLatest, - // collMod is called as part of the upgrade process to add the - // 'timeseriesBucketsMayHaveMixedSchemaData=true' catalog entry flag for time-series - // collections that are missing the flag. This indicates that the time-series - // collection existed in earlier server versions and may have mixed-schema data. - coll.getWritableCollection(opCtx)->setTimeseriesBucketsMayHaveMixedSchemaData(opCtx, - true); - } else if (currentVersion == - multiversion::GenericFCV::kDowngradingFromLatestToLastLTS) { - // (Generic FCV reference): While downgrading the FCV to kLastLTS, collMod is called - // as part of the downgrade process to remove the - // 'timeseriesBucketsMayHaveMixedSchemaData' catalog entry flag for time-series - // collections that have the flag. - coll.getWritableCollection(opCtx)->setTimeseriesBucketsMayHaveMixedSchemaData( - opCtx, boost::none); - } + if (coll->getTimeseriesOptions() && !coll->getTimeseriesBucketsMayHaveMixedSchemaData() && + (currentVersion == multiversion::GenericFCV::kUpgradingFromLastLTSToLatest || + currentVersion == multiversion::GenericFCV::kLatest)) { + // (Generic FCV reference): While upgrading the FCV from kLastLTS to kLatest, collMod is + // called as part of the upgrade process to add the + // 'timeseriesBucketsMayHaveMixedSchemaData=true' catalog entry flag for time-series + // collections that are missing the flag. This indicates that the time-series collection + // existed in earlier server versions and may have mixed-schema data. + coll.getWritableCollection(opCtx)->setTimeseriesBucketsMayHaveMixedSchemaData(opCtx, + true); + } else if (coll->getTimeseriesBucketsMayHaveMixedSchemaData() && + (currentVersion == multiversion::GenericFCV::kDowngradingFromLatestToLastLTS || + currentVersion == multiversion::GenericFCV::kLastLTS)) { + // (Generic FCV reference): While downgrading the FCV to kLastLTS, collMod is called as + // part of the downgrade process to remove the 'timeseriesBucketsMayHaveMixedSchemaData' + // catalog entry flag for time-series collections that have the flag. + coll.getWritableCollection(opCtx)->setTimeseriesBucketsMayHaveMixedSchemaData( + opCtx, boost::none); } // Only observe non-view collMods, as view operations are observed as operations on the @@ -1040,39 +963,6 @@ Status _collModInternal(OperationContext* opCtx, } // namespace -bool isCollModIndexUniqueConversion(const CollModRequest& request) { - auto index = request.getIndex(); - if (!index) { - return false; - } - if (auto indexUnique = index->getUnique(); !indexUnique) { - return false; - } - // Checks if the request is an actual unique conversion instead of a dry run. - if (auto dryRun = request.getDryRun(); dryRun && *dryRun) { - return false; - } - return true; -} - -CollModRequest makeCollModDryRunRequest(const CollModRequest& request) { - CollModRequest dryRunRequest; - CollModIndex dryRunIndex; - const auto& requestIndex = request.getIndex(); - dryRunIndex.setUnique(true); - if (auto keyPattern = requestIndex->getKeyPattern()) { - dryRunIndex.setKeyPattern(keyPattern); - } else if (auto name = requestIndex->getName()) { - dryRunIndex.setName(name); - } - if (auto uuid = request.getCollectionUUID()) { - dryRunRequest.setCollectionUUID(uuid); - } - dryRunRequest.setIndex(dryRunIndex); - dryRunRequest.setDryRun(true); - return dryRunRequest; -} - Status processCollModCommand(OperationContext* opCtx, const NamespaceStringOrUUID& nsOrUUID, const CollMod& cmd, |
