diff options
author | Arun Banala <arun.banala@mongodb.com> | 2021-08-25 15:53:30 +0100 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-08-31 16:18:15 +0000 |
commit | db491c42fffd8af3ceee9e39750913f613186ecb (patch) | |
tree | 47be35501ccc5a8c90ad3077f3fb1187f78ef5c6 /src/mongo/db | |
parent | a88433c2c78516e30b1356404df5cf977fe37c31 (diff) | |
download | mongo-db491c42fffd8af3ceee9e39750913f613186ecb.tar.gz |
SERVER-57572 Rewrite secondary indexes on mongos for sharded time-series collections
Diffstat (limited to 'src/mongo/db')
6 files changed, 135 insertions, 155 deletions
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp index 874c28d6c5e..258f54b3434 100644 --- a/src/mongo/db/commands/create_indexes.cpp +++ b/src/mongo/db/commands/create_indexes.cpp @@ -59,8 +59,8 @@ #include "mongo/db/s/database_sharding_state.h" #include "mongo/db/s/operation_sharding_state.h" #include "mongo/db/s/sharding_state.h" -#include "mongo/db/storage/storage_parameters_gen.h" #include "mongo/db/storage/two_phase_index_build_knobs_gen.h" +#include "mongo/db/timeseries/timeseries_commands_conversion_helper.h" #include "mongo/db/timeseries/timeseries_index_schema_conversion_functions.h" #include "mongo/db/timeseries/timeseries_options.h" #include "mongo/db/views/view_catalog.h" @@ -619,83 +619,6 @@ CreateIndexesReply runCreateIndexesWithCoordinator(OperationContext* opCtx, } /** - * Returns a CreateIndexesCommand for creating indexes on the bucket collection. - * Returns null if 'origCmd' is not for a time-series collection. - */ -std::unique_ptr<CreateIndexesCommand> makeTimeseriesCreateIndexesCommand( - OperationContext* opCtx, const CreateIndexesCommand& origCmd) { - const auto& origNs = origCmd.getNamespace(); - - auto timeseriesOptions = timeseries::getTimeseriesOptions(opCtx, origNs); - - // Return early with null if we are not working with a time-series collection. - if (!timeseriesOptions) { - return {}; - } - - const auto& origIndexes = origCmd.getIndexes(); - std::vector<mongo::BSONObj> indexes; - for (const auto& origIndex : origIndexes) { - BSONObjBuilder builder; - bool isBucketsIndexSpecCompatibleForDowngrade = false; - for (const auto& elem : origIndex) { - if (elem.fieldNameStringData() == NewIndexSpec::kKeyFieldName) { - auto pluginName = IndexNames::findPluginName(elem.Obj()); - uassert(ErrorCodes::InvalidOptions, - "Text indexes are not supported on time-series collections", - pluginName != IndexNames::TEXT); - - auto bucketsIndexSpecWithStatus = - timeseries::createBucketsIndexSpecFromTimeseriesIndexSpec(*timeseriesOptions, - elem.Obj()); - uassert(ErrorCodes::CannotCreateIndex, - str::stream() << bucketsIndexSpecWithStatus.getStatus().toString() - << " Command request: " << redact(origCmd.toBSON({})), - bucketsIndexSpecWithStatus.isOK()); - - isBucketsIndexSpecCompatibleForDowngrade = - timeseries::isBucketsIndexSpecCompatibleForDowngrade( - *timeseriesOptions, - BSON(NewIndexSpec::kKeyFieldName << bucketsIndexSpecWithStatus.getValue())); - - builder.append(NewIndexSpec::kKeyFieldName, - std::move(bucketsIndexSpecWithStatus.getValue())); - continue; - } - builder.append(elem); - if (elem.fieldNameStringData() == IndexDescriptor::kPartialFilterExprFieldName) { - uasserted(ErrorCodes::InvalidOptions, - "Partial indexes are not supported on time-series collections"); - } - - if (elem.fieldNameStringData() == IndexDescriptor::kExpireAfterSecondsFieldName) { - uasserted(ErrorCodes::InvalidOptions, - "TTL indexes are not supported on time-series collections"); - } - } - - if (feature_flags::gTimeseriesMetricIndexes.isEnabledAndIgnoreFCV() && - !isBucketsIndexSpecCompatibleForDowngrade) { - // Store the original user index definition on the transformed index definition for the - // time-series buckets collection if this is a newly supported index type on time-series - // collections. This is to avoid any additional downgrade steps for index types already - // supported in 5.0. - builder.appendObject(IndexDescriptor::kOriginalSpecFieldName, origIndex.objdata()); - } - - indexes.push_back(builder.obj()); - } - - auto ns = origNs.makeTimeseriesBucketsNamespace(); - auto cmd = std::make_unique<CreateIndexesCommand>(ns, std::move(indexes)); - cmd->setV(origCmd.getV()); - cmd->setIgnoreUnknownIndexOptions(origCmd.getIgnoreUnknownIndexOptions()); - cmd->setCommitQuorum(origCmd.getCommitQuorum()); - - return cmd; -} - -/** * { createIndexes : "bar", * indexes : [ { ns : "test.bar", key : { x : 1 }, name: "x_1" } ], * commitQuorum: "majority" } @@ -726,12 +649,13 @@ public: const auto& origCmd = request(); const auto* cmd = &origCmd; - // 'timeseriesCmd' is null if the request namespace does not refer to a time-series - // collection. Otherwise, transforms the user time-series index request to one on the - // underlying bucket. - auto timeseriesCmd = makeTimeseriesCreateIndexesCommand(opCtx, origCmd); - if (timeseriesCmd) { - cmd = timeseriesCmd.get(); + // If the request namespace refers to a time-series collection, transforms the user + // time-series index request to one on the underlying bucket. + boost::optional<CreateIndexesCommand> timeseriesCmdOwnership; + if (auto options = timeseries::getTimeseriesOptions(opCtx, origCmd.getNamespace())) { + timeseriesCmdOwnership = + timeseries::makeTimeseriesCreateIndexesCommand(opCtx, origCmd, *options); + cmd = ×eriesCmdOwnership.get(); } // If we encounter an IndexBuildAlreadyInProgress error for any of the requested index diff --git a/src/mongo/db/commands/drop_indexes.cpp b/src/mongo/db/commands/drop_indexes.cpp index 606b630fd4b..781e71259e6 100644 --- a/src/mongo/db/commands/drop_indexes.cpp +++ b/src/mongo/db/commands/drop_indexes.cpp @@ -51,7 +51,7 @@ #include "mongo/db/index_builds_coordinator.h" #include "mongo/db/op_observer.h" #include "mongo/db/service_context.h" -#include "mongo/db/timeseries/timeseries_index_schema_conversion_functions.h" +#include "mongo/db/timeseries/timeseries_commands_conversion_helper.h" #include "mongo/db/timeseries/timeseries_options.h" #include "mongo/db/vector_clock.h" #include "mongo/db/views/view_catalog.h" @@ -65,44 +65,6 @@ namespace { MONGO_FAIL_POINT_DEFINE(reIndexCrashAfterDrop); -/** - * Returns a DropIndexes for dropping indexes on the bucket collection. - * - * The 'index' dropIndexes parameter may refer to an index name, or array of names, or "*" for all - * indexes, or an index spec key (an object). Only the index spec key has to be translated for the - * bucket collection. The other forms of 'index' can be passed along unmodified. - * - * Returns null if 'origCmd' is not for a time-series collection. - */ -std::unique_ptr<DropIndexes> makeTimeseriesDropIndexesCommand(OperationContext* opCtx, - const DropIndexes& origCmd) { - const auto& origNs = origCmd.getNamespace(); - - auto timeseriesOptions = timeseries::getTimeseriesOptions(opCtx, origNs); - - // Return early with null if we are not working with a time-series collection. - if (!timeseriesOptions) { - return {}; - } - - auto ns = origNs.makeTimeseriesBucketsNamespace(); - - const auto& origIndex = origCmd.getIndex(); - if (auto keyPtr = stdx::get_if<BSONObj>(&origIndex)) { - auto bucketsIndexSpecWithStatus = - timeseries::createBucketsIndexSpecFromTimeseriesIndexSpec(*timeseriesOptions, *keyPtr); - - uassert(ErrorCodes::IndexNotFound, - str::stream() << bucketsIndexSpecWithStatus.getStatus().toString() - << " Command request: " << redact(origCmd.toBSON({})), - bucketsIndexSpecWithStatus.isOK()); - - return std::make_unique<DropIndexes>(ns, std::move(bucketsIndexSpecWithStatus.getValue())); - } - - return std::make_unique<DropIndexes>(ns, origIndex); -} - class CmdDropIndexes : public DropIndexesCmdVersion1Gen<CmdDropIndexes> { public: AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { @@ -134,8 +96,10 @@ public: Reply typedRun(OperationContext* opCtx) final { // If the request namespace refers to a time-series collection, transform the user // time-series index request to one on the underlying bucket. - if (auto timeseriesCmd = makeTimeseriesDropIndexesCommand(opCtx, request())) { - return dropIndexes(opCtx, timeseriesCmd->getNamespace(), timeseriesCmd->getIndex()); + if (auto options = timeseries::getTimeseriesOptions(opCtx, request().getNamespace())) { + auto timeseriesCmd = + timeseries::makeTimeseriesDropIndexesCommand(opCtx, request(), *options); + return dropIndexes(opCtx, timeseriesCmd.getNamespace(), timeseriesCmd.getIndex()); } return dropIndexes(opCtx, request().getNamespace(), request().getIndex()); diff --git a/src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp b/src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp index 32f3b4e2176..aa1b64889a5 100644 --- a/src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp +++ b/src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp @@ -29,19 +29,17 @@ #define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kStorage -#include "mongo/platform/basic.h" - #include "mongo/db/timeseries/timeseries_commands_conversion_helper.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/index_names.h" +#include "mongo/db/storage/storage_parameters_gen.h" #include "mongo/db/timeseries/timeseries_constants.h" -#include "mongo/db/timeseries/timeseries_gen.h" +#include "mongo/db/timeseries/timeseries_index_schema_conversion_functions.h" #include "mongo/logv2/log.h" +#include "mongo/logv2/redaction.h" -namespace mongo { - -namespace timeseries { +namespace mongo::timeseries { BSONObj makeTimeseriesCommand(const BSONObj& origCmd, const NamespaceString& ns, @@ -59,5 +57,93 @@ BSONObj makeTimeseriesCommand(const BSONObj& origCmd, return builder.obj(); } -} // namespace timeseries -} // namespace mongo +CreateIndexesCommand makeTimeseriesCreateIndexesCommand(OperationContext* opCtx, + const CreateIndexesCommand& origCmd, + const TimeseriesOptions& options) { + const auto& origNs = origCmd.getNamespace(); + const auto& origIndexes = origCmd.getIndexes(); + + std::vector<mongo::BSONObj> indexes; + for (const auto& origIndex : origIndexes) { + BSONObjBuilder builder; + bool isBucketsIndexSpecCompatibleForDowngrade = false; + for (const auto& elem : origIndex) { + if (elem.fieldNameStringData() == IndexDescriptor::kPartialFilterExprFieldName) { + uasserted(ErrorCodes::InvalidOptions, + "Partial indexes are not supported on time-series collections"); + } + + if (elem.fieldNameStringData() == IndexDescriptor::kExpireAfterSecondsFieldName) { + uasserted(ErrorCodes::InvalidOptions, + "TTL indexes are not supported on time-series collections"); + } + + if (elem.fieldNameStringData() == NewIndexSpec::kKeyFieldName) { + auto pluginName = IndexNames::findPluginName(elem.Obj()); + uassert(ErrorCodes::InvalidOptions, + "Text indexes are not supported on time-series collections", + pluginName != IndexNames::TEXT); + + auto bucketsIndexSpecWithStatus = + timeseries::createBucketsIndexSpecFromTimeseriesIndexSpec(options, elem.Obj()); + uassert(ErrorCodes::CannotCreateIndex, + str::stream() << bucketsIndexSpecWithStatus.getStatus().toString() + << " Command request: " << redact(origCmd.toBSON({})), + bucketsIndexSpecWithStatus.isOK()); + + isBucketsIndexSpecCompatibleForDowngrade = + timeseries::isBucketsIndexSpecCompatibleForDowngrade( + options, + BSON(NewIndexSpec::kKeyFieldName << bucketsIndexSpecWithStatus.getValue())); + + builder.append(NewIndexSpec::kKeyFieldName, + std::move(bucketsIndexSpecWithStatus.getValue())); + continue; + } + builder.append(elem); + } + + if (feature_flags::gTimeseriesMetricIndexes.isEnabledAndIgnoreFCV() && + !isBucketsIndexSpecCompatibleForDowngrade) { + // Store the original user index definition on the transformed index definition for the + // time-series buckets collection if this is a newly supported index type on time-series + // collections. This is to avoid any additional downgrade steps for index types already + // supported in 5.0. + builder.appendObject(IndexDescriptor::kOriginalSpecFieldName, origIndex.objdata()); + } + + indexes.push_back(builder.obj()); + } + + auto ns = origNs.makeTimeseriesBucketsNamespace(); + auto cmd = CreateIndexesCommand(ns, std::move(indexes)); + cmd.setV(origCmd.getV()); + cmd.setIgnoreUnknownIndexOptions(origCmd.getIgnoreUnknownIndexOptions()); + cmd.setCommitQuorum(origCmd.getCommitQuorum()); + + return cmd; +} + +DropIndexes makeTimeseriesDropIndexesCommand(OperationContext* opCtx, + const DropIndexes& origCmd, + const TimeseriesOptions& options) { + const auto& origNs = origCmd.getNamespace(); + auto ns = origNs.makeTimeseriesBucketsNamespace(); + + const auto& origIndex = origCmd.getIndex(); + if (auto keyPtr = stdx::get_if<BSONObj>(&origIndex)) { + auto bucketsIndexSpecWithStatus = + timeseries::createBucketsIndexSpecFromTimeseriesIndexSpec(options, *keyPtr); + + uassert(ErrorCodes::IndexNotFound, + str::stream() << bucketsIndexSpecWithStatus.getStatus().toString() + << " Command request: " << redact(origCmd.toBSON({})), + bucketsIndexSpecWithStatus.isOK()); + + return DropIndexes(ns, std::move(bucketsIndexSpecWithStatus.getValue())); + } + + return DropIndexes(ns, origIndex); +} + +} // namespace mongo::timeseries diff --git a/src/mongo/db/timeseries/timeseries_commands_conversion_helper.h b/src/mongo/db/timeseries/timeseries_commands_conversion_helper.h index 70452f34aab..eef1de61621 100644 --- a/src/mongo/db/timeseries/timeseries_commands_conversion_helper.h +++ b/src/mongo/db/timeseries/timeseries_commands_conversion_helper.h @@ -31,13 +31,12 @@ #include "mongo/base/status_with.h" #include "mongo/bson/bsonobj.h" +#include "mongo/db/create_indexes_gen.h" +#include "mongo/db/drop_indexes_gen.h" #include "mongo/db/namespace_string.h" +#include "mongo/db/timeseries/timeseries_gen.h" -namespace mongo { - -class OperationContext; -class TimeseriesOptions; -namespace timeseries { +namespace mongo::timeseries { /** * Returns a command object with time-series view namespace translated to bucket namespace. @@ -46,5 +45,22 @@ BSONObj makeTimeseriesCommand(const BSONObj& origCmd, const NamespaceString& ns, StringData nsFieldName); -} // namespace timeseries -} // namespace mongo +/* + * Returns a CreateIndexesCommand for creating indexes on the bucket collection. + */ +CreateIndexesCommand makeTimeseriesCreateIndexesCommand(OperationContext* opCtx, + const CreateIndexesCommand& origCmd, + const TimeseriesOptions& options); + +/** + * Returns a DropIndexes for dropping indexes on the bucket collection. + * + * The 'index' dropIndexes parameter may refer to an index name, or array of names, or "*" for all + * indexes, or an index spec key (an object). Only the index spec key has to be translated for the + * bucket collection. The other forms of 'index' can be passed along unmodified. + */ +DropIndexes makeTimeseriesDropIndexesCommand(OperationContext* opCtx, + const DropIndexes& origCmd, + const TimeseriesOptions& options); + +} // namespace mongo::timeseries diff --git a/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.cpp b/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.cpp index d322a749d49..276035bff16 100644 --- a/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.cpp +++ b/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.cpp @@ -29,8 +29,6 @@ #define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kStorage -#include "mongo/platform/basic.h" - #include "mongo/db/timeseries/timeseries_index_schema_conversion_functions.h" #include "mongo/db/index_names.h" @@ -40,9 +38,7 @@ #include "mongo/logv2/log.h" #include "mongo/logv2/redaction.h" -namespace mongo { - -namespace timeseries { +namespace mongo::timeseries { namespace { @@ -399,5 +395,4 @@ bool isBucketsIndexSpecCompatibleForDowngrade(const TimeseriesOptions& timeserie /*timeseriesMetricIndexesFeatureFlagEnabled=*/false) != boost::none; } -} // namespace timeseries -} // namespace mongo +} // namespace mongo::timeseries diff --git a/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.h b/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.h index d5c82b3f1ca..8e1240d9d16 100644 --- a/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.h +++ b/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.h @@ -31,17 +31,13 @@ #include "mongo/base/status_with.h" #include "mongo/bson/bsonobj.h" - -namespace mongo { - -class OperationContext; -class TimeseriesOptions; +#include "mongo/db/timeseries/timeseries_options.h" /** * Namespace for helper functions converting index spec schema between time-series collection and * underlying buckets collection. */ -namespace timeseries { +namespace mongo::timeseries { /** * Maps the time-series collection index spec 'timeseriesIndexSpecBSON' to the index schema of the @@ -80,5 +76,4 @@ std::list<BSONObj> createTimeseriesIndexesFromBucketsIndexes( bool isBucketsIndexSpecCompatibleForDowngrade(const TimeseriesOptions& timeseriesOptions, const BSONObj& bucketsIndex); -} // namespace timeseries -} // namespace mongo +} // namespace mongo::timeseries |