summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRui Liu <rui.liu@mongodb.com>2022-03-31 10:08:43 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-03-31 10:37:33 +0000
commite9f726e70620b1471c9a71599cc25919f43d7c31 (patch)
tree36054107527043d8f6bb7a93797f970462f51cf8
parent515ccf31288d759e1c82c59b789b3f8520622aba (diff)
downloadmongo-e9f726e70620b1471c9a71599cc25919f43d7c31.tar.gz
SERVER-64826 Upgrade/downgrade for collMod coordinator
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/upgrade_downgrade_timeseries_granularity_update.js42
-rw-r--r--jstests/sharding/timeseries_coll_mod.js15
-rw-r--r--src/mongo/db/commands/set_feature_compatibility_version_command.cpp2
-rw-r--r--src/mongo/db/s/SConscript1
-rw-r--r--src/mongo/db/s/collmod_coordinator_pre60_compatible.cpp251
-rw-r--r--src/mongo/db/s/collmod_coordinator_pre60_compatible.h97
-rw-r--r--src/mongo/db/s/sharding_ddl_coordinator.idl4
-rw-r--r--src/mongo/db/s/sharding_ddl_coordinator_service.cpp5
-rw-r--r--src/mongo/db/s/shardsvr_collmod_command.cpp32
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) {