diff options
Diffstat (limited to 'src/mongo')
7 files changed, 87 insertions, 22 deletions
diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript index cd2f7b33a87..f122a05c212 100644 --- a/src/mongo/db/commands/SConscript +++ b/src/mongo/db/commands/SConscript @@ -604,6 +604,7 @@ env.Library( '$BUILD_DIR/mongo/db/s/sharding_runtime_d', '$BUILD_DIR/mongo/db/s/transaction_coordinator', '$BUILD_DIR/mongo/db/s/user_writes_recoverable_critical_section', + '$BUILD_DIR/mongo/db/server_feature_flags', '$BUILD_DIR/mongo/db/server_options_core', '$BUILD_DIR/mongo/db/timeseries/timeseries_conversion_util', '$BUILD_DIR/mongo/idl/idl_parser', 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 6c20e3ae89c..2a540ffa88b 100644 --- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp +++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp @@ -64,6 +64,7 @@ #include "mongo/db/repl/tenant_migration_donor_service.h" #include "mongo/db/repl/tenant_migration_recipient_service.h" #include "mongo/db/s/active_migrations_registry.h" +#include "mongo/db/s/config/configsvr_coordinator_service.h" #include "mongo/db/s/config/sharding_catalog_manager.h" #include "mongo/db/s/migration_coordinator_document_gen.h" #include "mongo/db/s/migration_util.h" @@ -74,6 +75,7 @@ #include "mongo/db/s/sharding_ddl_coordinator_service.h" #include "mongo/db/s/sharding_util.h" #include "mongo/db/s/transaction_coordinator_service.h" +#include "mongo/db/server_feature_flags_gen.h" #include "mongo/db/server_options.h" #include "mongo/db/session_catalog.h" #include "mongo/db/session_txn_record_gen.h" @@ -383,6 +385,28 @@ public: } } + if (!gFeatureFlagUserWriteBlocking.isEnabledOnVersion(requestedVersion)) { + // TODO SERVER-65010 Remove this scope once 6.0 has branched out + + if (serverGlobalParams.clusterRole == ClusterRole::ConfigServer) { + uassert( + ErrorCodes::CannotDowngrade, + "Cannot downgrade while user write blocking is being changed", + ConfigsvrCoordinatorService::getService(opCtx) + ->isAnyCoordinatorOfGivenTypeRunning( + opCtx, ConfigsvrCoordinatorTypeEnum::kSetUserWriteBlockMode)); + } + + DBDirectClient client(opCtx); + + const bool isBlockingUserWrites = + client.count(NamespaceString::kUserWritesCriticalSectionsNamespace) != 0; + + uassert(ErrorCodes::CannotDowngrade, + "Cannot downgrade while user write blocking is enabled.", + !isBlockingUserWrites); + } + FeatureCompatibilityVersion::updateFeatureCompatibilityVersionDocument( opCtx, actualVersion, diff --git a/src/mongo/db/commands/set_user_write_block_mode_command.cpp b/src/mongo/db/commands/set_user_write_block_mode_command.cpp index ab55073c714..b1d645dda4b 100644 --- a/src/mongo/db/commands/set_user_write_block_mode_command.cpp +++ b/src/mongo/db/commands/set_user_write_block_mode_command.cpp @@ -33,15 +33,17 @@ #include "mongo/db/auth/authorization_session.h" #include "mongo/db/commands.h" +#include "mongo/db/commands/feature_compatibility_version.h" #include "mongo/db/commands/set_user_write_block_mode_gen.h" #include "mongo/db/repl/repl_client_info.h" #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/s/user_writes_recoverable_critical_section_service.h" +#include "mongo/db/server_feature_flags_gen.h" #include "mongo/logv2/log.h" - namespace mongo { namespace { + class SetUserWriteBlockModeCommand final : public TypedCommand<SetUserWriteBlockModeCommand> { public: using Request = SetUserWriteBlockMode; @@ -73,6 +75,13 @@ public: repl::ReplicationCoordinator::modeNone); { + // TODO SERVER-65010 Remove FCV guard once 6.0 has branched out + FixedFCVRegion fixedFcvRegion(opCtx); + uassert(ErrorCodes::IllegalOperation, + "featureFlagUserWriteBlocking not enabled", + gFeatureFlagUserWriteBlocking.isEnabled( + serverGlobalParams.featureCompatibility)); + if (request().getGlobal()) { UserWritesRecoverableCriticalSectionService::get(opCtx) ->acquireRecoverableCriticalSectionBlockingUserWrites( @@ -86,17 +95,17 @@ public: UserWritesRecoverableCriticalSectionService:: kGlobalUserWritesNamespace); } - - // Wait for the writes to the UserWritesRecoverableCriticalSection collection to be - // majority commited. - auto& replClient = repl::ReplClientInfo::forClient(opCtx->getClient()); - WriteConcernResult writeConcernResult; - WriteConcernOptions majority(WriteConcernOptions::kMajority, - WriteConcernOptions::SyncMode::UNSET, - WriteConcernOptions::kWriteConcernTimeoutUserCommand); - uassertStatusOK(waitForWriteConcern( - opCtx, replClient.getLastOp(), majority, &writeConcernResult)); } + + // Wait for the writes to the UserWritesRecoverableCriticalSection collection to be + // majority commited. + auto& replClient = repl::ReplClientInfo::forClient(opCtx->getClient()); + WriteConcernResult writeConcernResult; + WriteConcernOptions majority(WriteConcernOptions::kMajority, + WriteConcernOptions::SyncMode::UNSET, + WriteConcernOptions::kWriteConcernTimeoutUserCommand); + uassertStatusOK( + waitForWriteConcern(opCtx, replClient.getLastOp(), majority, &writeConcernResult)); } private: diff --git a/src/mongo/db/s/config/configsvr_coordinator.h b/src/mongo/db/s/config/configsvr_coordinator.h index 6c7facecb9a..ff6d6de23dc 100644 --- a/src/mongo/db/s/config/configsvr_coordinator.h +++ b/src/mongo/db/s/config/configsvr_coordinator.h @@ -56,6 +56,10 @@ public: virtual bool hasSameOptions(const BSONObj&) const = 0; + ConfigsvrCoordinatorTypeEnum coordinatorType() const { + return _coordId.getCoordinatorType(); + } + protected: const ConfigsvrCoordinatorId _coordId; diff --git a/src/mongo/db/s/config/configsvr_coordinator_service.cpp b/src/mongo/db/s/config/configsvr_coordinator_service.cpp index 1a30da0a9b4..b3ba449ac0f 100644 --- a/src/mongo/db/s/config/configsvr_coordinator_service.cpp +++ b/src/mongo/db/s/config/configsvr_coordinator_service.cpp @@ -93,4 +93,20 @@ ConfigsvrCoordinatorService::constructInstance(BSONObj initialState) { } } +bool ConfigsvrCoordinatorService::isAnyCoordinatorOfGivenTypeRunning( + OperationContext* opCtx, ConfigsvrCoordinatorTypeEnum coordinatorType) { + + const auto instances = getAllInstances(opCtx); + for (const auto& instance : instances) { + auto typedInstance = checked_pointer_cast<ConfigsvrCoordinator>(instance); + if (typedInstance->coordinatorType() == coordinatorType) { + if (!typedInstance->getCompletionFuture().isReady()) { + return false; + } + } + } + + return true; +} + } // namespace mongo diff --git a/src/mongo/db/s/config/configsvr_coordinator_service.h b/src/mongo/db/s/config/configsvr_coordinator_service.h index 0d022edfef8..7b8f30a3ed3 100644 --- a/src/mongo/db/s/config/configsvr_coordinator_service.h +++ b/src/mongo/db/s/config/configsvr_coordinator_service.h @@ -67,6 +67,9 @@ public: const std::vector<const PrimaryOnlyService::Instance*>& existingInstances) override{}; std::shared_ptr<Instance> constructInstance(BSONObj initialState) override; + + bool isAnyCoordinatorOfGivenTypeRunning(OperationContext* opCtx, + ConfigsvrCoordinatorTypeEnum coordinatorType); }; } // namespace mongo diff --git a/src/mongo/db/s/config/configsvr_set_user_write_block_mode_command.cpp b/src/mongo/db/s/config/configsvr_set_user_write_block_mode_command.cpp index de09fb92539..05414da45f9 100644 --- a/src/mongo/db/s/config/configsvr_set_user_write_block_mode_command.cpp +++ b/src/mongo/db/s/config/configsvr_set_user_write_block_mode_command.cpp @@ -33,6 +33,7 @@ #include "mongo/db/auth/authorization_session.h" #include "mongo/db/commands.h" +#include "mongo/db/commands/feature_compatibility_version.h" #include "mongo/db/s/config/configsvr_coordinator_service.h" #include "mongo/db/s/config/set_user_write_block_mode_coordinator.h" #include "mongo/db/server_feature_flags_gen.h" @@ -58,22 +59,29 @@ public: serverGlobalParams.clusterRole == ClusterRole::ConfigServer); CommandHelpers::uassertCommandRunWithMajority(Request::kCommandName, opCtx->getWriteConcern()); - uassert( - ErrorCodes::IllegalOperation, - "featureFlagUserWriteBlocking not enabled", - gFeatureFlagUserWriteBlocking.isEnabled(serverGlobalParams.featureCompatibility)); const auto startBlocking = request().getGlobal(); - SetUserWriteBlockModeCoordinatorDocument coordinatorDoc{startBlocking}; - coordinatorDoc.setConfigsvrCoordinatorMetadata( - {ConfigsvrCoordinatorTypeEnum::kSetUserWriteBlockMode}); - const auto coordinatorDocBSON = coordinatorDoc.toBSON(); + const auto coordinatorCompletionFuture = [&]() -> SharedSemiFuture<void> { + // TODO SERVER-65010 Remove FCV guard once 6.0 has branched out + FixedFCVRegion fixedFcvRegion(opCtx); + uassert(ErrorCodes::IllegalOperation, + "featureFlagUserWriteBlocking not enabled", + gFeatureFlagUserWriteBlocking.isEnabled( + serverGlobalParams.featureCompatibility)); - const auto service = ConfigsvrCoordinatorService::getService(opCtx); - const auto instance = service->getOrCreateService(opCtx, coordinatorDoc.toBSON()); + SetUserWriteBlockModeCoordinatorDocument coordinatorDoc{startBlocking}; + coordinatorDoc.setConfigsvrCoordinatorMetadata( + {ConfigsvrCoordinatorTypeEnum::kSetUserWriteBlockMode}); + const auto coordinatorDocBSON = coordinatorDoc.toBSON(); - instance->getCompletionFuture().get(opCtx); + const auto service = ConfigsvrCoordinatorService::getService(opCtx); + const auto instance = service->getOrCreateService(opCtx, coordinatorDoc.toBSON()); + + return instance->getCompletionFuture(); + }(); + + coordinatorCompletionFuture.get(opCtx); } private: |