diff options
author | Rui Liu <rui.liu@mongodb.com> | 2022-03-31 10:08:43 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-03-31 10:37:33 +0000 |
commit | e9f726e70620b1471c9a71599cc25919f43d7c31 (patch) | |
tree | 36054107527043d8f6bb7a93797f970462f51cf8 | |
parent | 515ccf31288d759e1c82c59b789b3f8520622aba (diff) | |
download | mongo-e9f726e70620b1471c9a71599cc25919f43d7c31.tar.gz |
SERVER-64826 Upgrade/downgrade for collMod coordinator
9 files changed, 437 insertions, 12 deletions
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/upgrade_downgrade_timeseries_granularity_update.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/upgrade_downgrade_timeseries_granularity_update.js new file mode 100644 index 00000000000..354dea0f820 --- /dev/null +++ b/jstests/multiVersion/targetedTestsLastLtsFeatures/upgrade_downgrade_timeseries_granularity_update.js @@ -0,0 +1,42 @@ +/** + * Tests that granularity update for sharded time-series collections is disabled for FCV < 6.0 + */ +(function() { +"use strict"; + +load('./jstests/multiVersion/libs/multi_cluster.js'); + +function runTest(downgradeVersion) { + const st = new ShardingTest({shards: 1}); + const dbName = "test"; + const collName = jsTestName(); + const viewNss = `${dbName}.${collName}`; + const timeField = "time"; + const metaField = "meta"; + const mongos = st.s; + const db = mongos.getDB(dbName); + + assert.commandWorked(mongos.adminCommand({enableSharding: dbName})); + assert.commandWorked(db.createCollection( + collName, + {timeseries: {timeField: timeField, metaField: metaField, granularity: 'seconds'}})); + assert.commandWorked(mongos.adminCommand({ + shardCollection: viewNss, + key: {[metaField]: 1}, + })); + + // Granularity updates works in 6.0 + assert.commandWorked(db.runCommand({collMod: collName, timeseries: {granularity: 'minutes'}})); + + // Granularity updates fails after downgrading. + assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: downgradeVersion})); + assert.commandFailedWithCode( + db.runCommand({collMod: collName, timeseries: {granularity: 'hours'}}), + ErrorCodes.NotImplemented); + + st.stop(); +} + +runTest(lastLTSFCV); +runTest(lastContinuousFCV); +})(); diff --git a/jstests/sharding/timeseries_coll_mod.js b/jstests/sharding/timeseries_coll_mod.js index 77aed7d5177..27792055a47 100644 --- a/jstests/sharding/timeseries_coll_mod.js +++ b/jstests/sharding/timeseries_coll_mod.js @@ -22,7 +22,7 @@ const viewNss = `${dbName}.${collName}`; const bucketNss = `${dbName}.system.buckets.${collName}`; const controlTimeField = `control.min.${timeField}`; -function runBasicTest(primaryDispatching) { +function runBasicTest(failPoint) { const st = new ShardingTest({shards: 2, rs: {nodes: 2}}); const mongos = st.s0; const db = mongos.getDB(dbName); @@ -39,10 +39,10 @@ function runBasicTest(primaryDispatching) { // Setting collModPrimaryDispatching failpoint to make sure the fallback logic of dispatching // collMod command at primary shard works. - if (primaryDispatching) { + if (failPoint) { const primary = st.getPrimaryShard(dbName); - assert.commandWorked(primary.adminCommand( - {configureFailPoint: 'collModPrimaryDispatching', mode: 'alwaysOn'})); + assert.commandWorked( + primary.adminCommand({configureFailPoint: failPoint, mode: 'alwaysOn'})); } // Updates for timeField and metaField are disabled. @@ -74,7 +74,7 @@ function runBasicTest(primaryDispatching) { assert.commandWorked( db.runCommand({collMod: collName, index: {name: indexName, hidden: false}})); - if (primaryDispatching) { + if (failPoint) { // Granularity update disabled for sharded time-series collection, when we're using primary // dispatching logic. assert.commandFailedWithCode( @@ -175,8 +175,9 @@ function runReadAfterWriteTest() { st.stop(); } -runBasicTest(false); -runBasicTest(true); +runBasicTest('collModPrimaryDispatching'); +runBasicTest('collModCoordinatorPre60Compatible'); +runBasicTest(); runReadAfterWriteTest(); })(); 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 13c8e238bcc..01ce1c396b7 100644 --- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp +++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp @@ -403,7 +403,7 @@ public: // TODO (SERVER-62325): Remove collMod draining mechanism after 6.0 branching. if (actualVersion > requestedVersion && - requestedVersion < multiversion::FeatureCompatibilityVersion::kVersion_5_3) { + requestedVersion < multiversion::FeatureCompatibilityVersion::kVersion_6_0) { // No more collMod coordinators will start because we have already switched // the FCV value to kDowngrading. Wait for the ongoing collMod coordinators to // finish. diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript index 1ef790b7756..bc2977f8f1c 100644 --- a/src/mongo/db/s/SConscript +++ b/src/mongo/db/s/SConscript @@ -317,6 +317,7 @@ env.Library( 'cluster_write_cmd_d.cpp', 'collmod_coordinator.cpp', 'collmod_coordinator_document.idl', + 'collmod_coordinator_pre60_compatible.cpp', 'config/set_cluster_parameter_coordinator.cpp', 'config/set_cluster_parameter_coordinator_document.idl', 'config/set_user_write_block_mode_coordinator.cpp', diff --git a/src/mongo/db/s/collmod_coordinator_pre60_compatible.cpp b/src/mongo/db/s/collmod_coordinator_pre60_compatible.cpp new file mode 100644 index 00000000000..fad015c8fd7 --- /dev/null +++ b/src/mongo/db/s/collmod_coordinator_pre60_compatible.cpp @@ -0,0 +1,251 @@ +/** + * Copyright (C) 2021-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kSharding + +#include "mongo/db/s/collmod_coordinator_pre60_compatible.h" + +#include "mongo/db/catalog/collection_catalog.h" +#include "mongo/db/catalog/database_holder.h" +#include "mongo/db/coll_mod_gen.h" +#include "mongo/db/db_raii.h" +#include "mongo/db/ops/insert.h" +#include "mongo/db/s/sharded_collmod_gen.h" +#include "mongo/db/s/sharding_ddl_util.h" +#include "mongo/db/s/sharding_state.h" +#include "mongo/db/timeseries/catalog_helper.h" +#include "mongo/db/timeseries/timeseries_collmod.h" +#include "mongo/idl/idl_parser.h" +#include "mongo/logv2/log.h" +#include "mongo/s/async_requests_sender.h" +#include "mongo/s/cluster_commands_helpers.h" +#include "mongo/s/grid.h" + +namespace mongo { + +namespace { + +bool isShardedColl(OperationContext* opCtx, const NamespaceString& nss) { + try { + auto coll = Grid::get(opCtx)->catalogClient()->getCollection(opCtx, nss); + return true; + } catch (const ExceptionFor<ErrorCodes::NamespaceNotFound>&) { + // The collection is not sharded or doesn't exist. + return false; + } +} + +bool hasTimeSeriesGranularityUpdate(const CollModRequest& request) { + return request.getTimeseries() && request.getTimeseries()->getGranularity(); +} + +} // namespace + +CollModCoordinatorPre60Compatible::CollModCoordinatorPre60Compatible( + ShardingDDLCoordinatorService* service, const BSONObj& initialState) + : ShardingDDLCoordinator(service, initialState) { + _initialState = initialState.getOwned(); + _doc = CollModCoordinatorDocument::parse(IDLParserErrorContext("CollModCoordinatorDocument"), + _initialState); +} + +void CollModCoordinatorPre60Compatible::checkIfOptionsConflict(const BSONObj& doc) const { + const auto otherDoc = + CollModCoordinatorDocument::parse(IDLParserErrorContext("CollModCoordinatorDocument"), doc); + + const auto& selfReq = _doc.getCollModRequest().toBSON(); + const auto& otherReq = otherDoc.getCollModRequest().toBSON(); + + uassert(ErrorCodes::ConflictingOperationInProgress, + str::stream() << "Another collMod for namespace " << nss() + << " is being executed with different parameters: " << selfReq, + SimpleBSONObjComparator::kInstance.evaluate(selfReq == otherReq)); +} + +boost::optional<BSONObj> CollModCoordinatorPre60Compatible::reportForCurrentOp( + MongoProcessInterface::CurrentOpConnectionsMode connMode, + MongoProcessInterface::CurrentOpSessionsMode sessionMode) noexcept { + + BSONObjBuilder cmdBob; + if (const auto& optComment = getForwardableOpMetadata().getComment()) { + cmdBob.append(optComment.get().firstElement()); + } + cmdBob.appendElements(_doc.getCollModRequest().toBSON()); + BSONObjBuilder bob; + bob.append("type", "op"); + bob.append("desc", "CollModCoordinator"); + bob.append("op", "command"); + bob.append("ns", nss().toString()); + bob.append("command", cmdBob.obj()); + bob.append("currentPhase", _doc.getPhase()); + bob.append("active", true); + return bob.obj(); +} + +void CollModCoordinatorPre60Compatible::_enterPhase(Phase newPhase) { + StateDoc newDoc(_doc); + newDoc.setPhase(newPhase); + + LOGV2_DEBUG(6482601, + 2, + "CollMod coordinator phase transition", + "namespace"_attr = nss(), + "newPhase"_attr = CollModCoordinatorPhase_serializer(newDoc.getPhase()), + "oldPhase"_attr = CollModCoordinatorPhase_serializer(_doc.getPhase())); + + if (_doc.getPhase() == Phase::kUnset) { + _doc = _insertStateDocument(std::move(newDoc)); + return; + } + _doc = _updateStateDocument(cc().makeOperationContext().get(), std::move(newDoc)); +} + +void CollModCoordinatorPre60Compatible::_performNoopRetryableWriteOnParticipants( + OperationContext* opCtx, const std::shared_ptr<executor::TaskExecutor>& executor) { + auto shardsAndConfigsvr = [&] { + const auto shardRegistry = Grid::get(opCtx)->shardRegistry(); + auto participants = shardRegistry->getAllShardIds(opCtx); + participants.emplace_back(shardRegistry->getConfigShard()->getId()); + return participants; + }(); + + _doc = _updateSession(opCtx, _doc); + sharding_ddl_util::performNoopRetryableWriteOnShards( + opCtx, shardsAndConfigsvr, getCurrentSession(_doc), executor); +} + +ExecutorFuture<void> CollModCoordinatorPre60Compatible::_runImpl( + std::shared_ptr<executor::ScopedTaskExecutor> executor, + const CancellationToken& token) noexcept { + return ExecutorFuture<void>(**executor) + .then(_executePhase( + Phase::kUpdateShards, + [this, executor = executor, anchor = shared_from_this()] { + auto opCtxHolder = cc().makeOperationContext(); + auto* opCtx = opCtxHolder.get(); + getForwardableOpMetadata().setOn(opCtx); + + const auto isTimeSeries = timeseries::getTimeseriesOptions( + opCtx, nss(), !nss().isTimeseriesBucketsCollection()); + const auto collNss = isTimeSeries && !nss().isTimeseriesBucketsCollection() + ? nss().makeTimeseriesBucketsNamespace() + : nss(); + const auto isSharded = isShardedColl(opCtx, collNss); + + if (isSharded) { + // Updating granularity on sharded time-series collections is not allowed. + if (isTimeSeries) { + uassert( + ErrorCodes::NotImplemented, + str::stream() + << "Cannot update granularity of a sharded time-series collection.", + !hasTimeSeriesGranularityUpdate(_doc.getCollModRequest())); + } + _doc.setCollUUID( + sharding_ddl_util::getCollectionUUID(opCtx, nss(), true /* allowViews */)); + + sharding_ddl_util::stopMigrations(opCtx, nss(), _doc.getCollUUID()); + + if (!_firstExecution) { + _performNoopRetryableWriteOnParticipants(opCtx, **executor); + } + + _doc = _updateSession(opCtx, _doc); + const OperationSessionInfo osi = getCurrentSession(_doc); + + const auto chunkManager = uassertStatusOK( + Grid::get(opCtx)->catalogCache()->getCollectionRoutingInfoWithRefresh( + opCtx, collNss)); + std::unique_ptr<CollatorInterface> collator; + const auto expCtx = + make_intrusive<ExpressionContext>(opCtx, std::move(collator), collNss); + std::set<ShardId> participants; + chunkManager.getShardIdsForQuery( + expCtx, {} /* query */, {} /* collation */, &participants); + + ShardsvrCollModParticipant request(nss(), _doc.getCollModRequest()); + const auto cmdObj = + CommandHelpers::appendMajorityWriteConcern(request.toBSON({})); + const auto& responses = sharding_ddl_util::sendAuthenticatedCommandToShards( + opCtx, + nss().db(), + cmdObj.addFields(osi.toBSON()), + {std::make_move_iterator(participants.begin()), + std::make_move_iterator(participants.end())}, + **executor); + BSONObjBuilder builder; + std::string errmsg; + auto ok = appendRawResponses(opCtx, &errmsg, &builder, responses).responseOK; + if (!errmsg.empty()) { + CommandHelpers::appendSimpleCommandStatus(builder, ok, errmsg); + } + _result = builder.obj(); + sharding_ddl_util::resumeMigrations(opCtx, nss(), _doc.getCollUUID()); + } else { + CollMod cmd(nss()); + cmd.setCollModRequest(_doc.getCollModRequest()); + BSONObjBuilder collModResBuilder; + uassertStatusOK(timeseries::processCollModCommandWithTimeSeriesTranslation( + opCtx, nss(), cmd, true, &collModResBuilder)); + auto collModRes = collModResBuilder.obj(); + + const auto dbInfo = uassertStatusOK( + Grid::get(opCtx)->catalogCache()->getDatabase(opCtx, nss().db())); + const auto shard = uassertStatusOK( + Grid::get(opCtx)->shardRegistry()->getShard(opCtx, dbInfo->getPrimary())); + BSONObjBuilder builder; + builder.appendElements(collModRes); + BSONObjBuilder subBuilder(builder.subobjStart("raw")); + subBuilder.append(shard->getConnString().toString(), collModRes); + subBuilder.doneFast(); + _result = builder.obj(); + } + })) + .onError([this, anchor = shared_from_this()](const Status& status) { + if (!status.isA<ErrorCategory::NotPrimaryError>() && + !status.isA<ErrorCategory::ShutdownError>()) { + LOGV2_ERROR(6482602, + "Error running collMod", + "namespace"_attr = nss(), + "error"_attr = redact(status)); + // If we have the collection UUID set, this error happened in a sharded collection, + // we should restore the migrations. + if (_doc.getCollUUID()) { + auto opCtxHolder = cc().makeOperationContext(); + auto* opCtx = opCtxHolder.get(); + getForwardableOpMetadata().setOn(opCtx); + + sharding_ddl_util::resumeMigrations(opCtx, nss(), _doc.getCollUUID()); + } + } + return status; + }); +} + +} // namespace mongo diff --git a/src/mongo/db/s/collmod_coordinator_pre60_compatible.h b/src/mongo/db/s/collmod_coordinator_pre60_compatible.h new file mode 100644 index 00000000000..29c250dc452 --- /dev/null +++ b/src/mongo/db/s/collmod_coordinator_pre60_compatible.h @@ -0,0 +1,97 @@ +/** + * Copyright (C) 2021-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/db/s/collmod_coordinator_document_gen.h" +#include "mongo/db/s/sharding_ddl_coordinator.h" +#include "mongo/s/request_types/sharded_ddl_commands_gen.h" + +namespace mongo { + +class CollModCoordinatorPre60Compatible final : public ShardingDDLCoordinator { +public: + using StateDoc = CollModCoordinatorDocument; + using Phase = CollModCoordinatorPhaseEnum; + + CollModCoordinatorPre60Compatible(ShardingDDLCoordinatorService* service, + const BSONObj& initialState); + + void checkIfOptionsConflict(const BSONObj& doc) const override; + + boost::optional<BSONObj> reportForCurrentOp( + MongoProcessInterface::CurrentOpConnectionsMode connMode, + MongoProcessInterface::CurrentOpSessionsMode sessionMode) noexcept override; + + /** + * Waits for the termination of the parent DDLCoordinator (so all the resources are liberated) + * and then return the result. + */ + BSONObj getResult(OperationContext* opCtx) { + getCompletionFuture().get(opCtx); + invariant(_result.is_initialized()); + return *_result; + } + +private: + ShardingDDLCoordinatorMetadata const& metadata() const override { + return _doc.getShardingDDLCoordinatorMetadata(); + } + + ExecutorFuture<void> _runImpl(std::shared_ptr<executor::ScopedTaskExecutor> executor, + const CancellationToken& token) noexcept override; + + template <typename Func> + auto _executePhase(const Phase& newPhase, Func&& func) { + return [=] { + const auto& currPhase = _doc.getPhase(); + + if (currPhase > newPhase) { + // Do not execute this phase if we already reached a subsequent one. + return; + } + if (currPhase < newPhase) { + // Persist the new phase if this is the first time we are executing it. + _enterPhase(newPhase); + } + return func(); + }; + } + + void _enterPhase(Phase newPhase); + + void _performNoopRetryableWriteOnParticipants( + OperationContext* opCtx, const std::shared_ptr<executor::TaskExecutor>& executor); + + BSONObj _initialState; + CollModCoordinatorDocument _doc; + boost::optional<BSONObj> _result; +}; + +} // namespace mongo diff --git a/src/mongo/db/s/sharding_ddl_coordinator.idl b/src/mongo/db/s/sharding_ddl_coordinator.idl index 075da6a47d8..eb0b7e88590 100644 --- a/src/mongo/db/s/sharding_ddl_coordinator.idl +++ b/src/mongo/db/s/sharding_ddl_coordinator.idl @@ -53,7 +53,9 @@ enums: kRefineCollectionShardKey: "refineCollectionShardKey" kRefineCollectionShardKeyNoResilient: "refineCollectionShardKeyNoResilient" kSetAllowMigrations: "setAllowMigrations" - kCollMod: "collMod" + # TODO (SERVER-62325): Remove pre60 compatible collMod coordinator after 6.0 branching. + kCollModPre60Compatible: "collMod" + kCollMod: "collMod_V2" kReshardCollection: "reshardCollection" kReshardCollectionNoResilient: "reshardCollectionNoResilient" diff --git a/src/mongo/db/s/sharding_ddl_coordinator_service.cpp b/src/mongo/db/s/sharding_ddl_coordinator_service.cpp index 3d889877423..60e288f2082 100644 --- a/src/mongo/db/s/sharding_ddl_coordinator_service.cpp +++ b/src/mongo/db/s/sharding_ddl_coordinator_service.cpp @@ -39,6 +39,7 @@ #include "mongo/db/pipeline/document_source_count.h" #include "mongo/db/pipeline/expression_context.h" #include "mongo/db/s/collmod_coordinator.h" +#include "mongo/db/s/collmod_coordinator_pre60_compatible.h" #include "mongo/db/s/create_collection_coordinator.h" #include "mongo/db/s/database_sharding_state.h" #include "mongo/db/s/drop_collection_coordinator.h" @@ -94,6 +95,10 @@ std::shared_ptr<ShardingDDLCoordinator> constructShardingDDLCoordinatorInstance( case DDLCoordinatorTypeEnum::kCollMod: return std::make_shared<CollModCoordinator>(service, std::move(initialState)); break; + case DDLCoordinatorTypeEnum::kCollModPre60Compatible: + return std::make_shared<CollModCoordinatorPre60Compatible>(service, + std::move(initialState)); + break; case DDLCoordinatorTypeEnum::kReshardCollection: return std::make_shared<ReshardCollectionCoordinator>(service, std::move(initialState)); break; diff --git a/src/mongo/db/s/shardsvr_collmod_command.cpp b/src/mongo/db/s/shardsvr_collmod_command.cpp index ab5516c9f63..97f47538531 100644 --- a/src/mongo/db/s/shardsvr_collmod_command.cpp +++ b/src/mongo/db/s/shardsvr_collmod_command.cpp @@ -37,6 +37,7 @@ #include "mongo/db/commands/feature_compatibility_version.h" #include "mongo/db/curop.h" #include "mongo/db/s/collmod_coordinator.h" +#include "mongo/db/s/collmod_coordinator_pre60_compatible.h" #include "mongo/db/s/sharding_state.h" #include "mongo/db/s/sharding_util.h" #include "mongo/db/timeseries/catalog_helper.h" @@ -51,6 +52,7 @@ namespace mongo { namespace { MONGO_FAIL_POINT_DEFINE(collModPrimaryDispatching); +MONGO_FAIL_POINT_DEFINE(collModCoordinatorPre60Compatible); class ShardsvrCollModCommand final : public BasicCommandWithRequestParser<ShardsvrCollModCommand> { public: @@ -109,10 +111,18 @@ public: boost::optional<FixedFCVRegion> fcvRegion; fcvRegion.emplace(opCtx); - bool useDDLCoordinator = fcvRegion.get()->isGreaterThanOrEqualTo( - multiversion::FeatureCompatibilityVersion::kVersion_5_3); - if (MONGO_unlikely(collModPrimaryDispatching.shouldFail()) || !useDDLCoordinator) { + + if (MONGO_unlikely(collModPrimaryDispatching.shouldFail())) { + return runWithDispatchingCommands(opCtx, result, cmd); + } else if (MONGO_unlikely(collModCoordinatorPre60Compatible.shouldFail())) { + return runWithDDLCoordinatorPre60Compatible(opCtx, result, cmd, fcvRegion); + } + + if (fcvRegion.get()->isLessThan(multiversion::FeatureCompatibilityVersion::kVersion_5_3)) { return runWithDispatchingCommands(opCtx, result, cmd); + } else if (fcvRegion.get()->isLessThan( + multiversion::FeatureCompatibilityVersion::kVersion_6_0)) { + return runWithDDLCoordinatorPre60Compatible(opCtx, result, cmd, fcvRegion); } else { return runWithDDLCoordinator(opCtx, result, cmd, fcvRegion); } @@ -134,6 +144,22 @@ public: return true; } + bool runWithDDLCoordinatorPre60Compatible(OperationContext* opCtx, + BSONObjBuilder& result, + const ShardsvrCollMod& cmd, + boost::optional<FixedFCVRegion>& fcvRegion) { + auto coordinatorDoc = CollModCoordinatorDocument(); + coordinatorDoc.setCollModRequest(cmd.getCollModRequest()); + coordinatorDoc.setShardingDDLCoordinatorMetadata( + {{cmd.getNamespace(), DDLCoordinatorTypeEnum::kCollModPre60Compatible}}); + auto service = ShardingDDLCoordinatorService::getService(opCtx); + auto collModCoordinator = checked_pointer_cast<CollModCoordinatorPre60Compatible>( + service->getOrCreateInstance(opCtx, coordinatorDoc.toBSON())); + fcvRegion = boost::none; + result.appendElements(collModCoordinator->getResult(opCtx)); + return true; + } + bool runWithDispatchingCommands(OperationContext* opCtx, BSONObjBuilder& result, const ShardsvrCollMod& cmd) { |