summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/coll_mod.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/catalog/coll_mod.cpp')
-rw-r--r--src/mongo/db/catalog/coll_mod.cpp170
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,