diff options
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/commands/rwc_defaults_commands.cpp | 18 | ||||
-rw-r--r-- | src/mongo/db/repl/repl_set_config.cpp | 23 | ||||
-rw-r--r-- | src/mongo/db/repl/repl_set_config.h | 6 | ||||
-rw-r--r-- | src/mongo/db/repl/repl_set_config_test.cpp | 187 | ||||
-rw-r--r-- | src/mongo/db/repl/repl_set_tag.h | 31 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_coordinator.h | 22 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_impl.cpp | 52 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_impl.h | 72 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_mock.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_mock.h | 15 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_noop.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_noop.h | 15 | ||||
-rw-r--r-- | src/mongo/embedded/replication_coordinator_embedded.cpp | 5 | ||||
-rw-r--r-- | src/mongo/embedded/replication_coordinator_embedded.h | 15 |
14 files changed, 471 insertions, 2 deletions
diff --git a/src/mongo/db/commands/rwc_defaults_commands.cpp b/src/mongo/db/commands/rwc_defaults_commands.cpp index f02cd506186..7fd405804f9 100644 --- a/src/mongo/db/commands/rwc_defaults_commands.cpp +++ b/src/mongo/db/commands/rwc_defaults_commands.cpp @@ -42,10 +42,14 @@ #include "mongo/db/repl/replication_coordinator.h" #include "mongo/logv2/log.h" #include "mongo/rpc/get_status_from_command_result.h" +#include "mongo/util/fail_point.h" namespace mongo { namespace { +// Hang during the execution of SetDefaultRWConcernCommand. +MONGO_FAIL_POINT_DEFINE(hangWhileSettingDefaultRWC); + /** * Replaces the persisted default read/write concern document with a new one representing the given * defaults. Waits for the write concern on the given operation context to be satisfied before @@ -113,6 +117,17 @@ public: auto typedRun(OperationContext* opCtx) { assertNotStandaloneOrShardServer(opCtx, SetDefaultRWConcern::kCommandName); + auto replCoord = repl::ReplicationCoordinator::get(opCtx); + auto wcChanges = replCoord->getWriteConcernTagChanges(); + + // Synchronize this change with potential changes to the write concern tags. + uassert(ErrorCodes::ConfigurationInProgress, + "Replica set reconfig in progress. Please retry the command later.", + wcChanges->reserveDefaultWriteConcernChange()); + ON_BLOCK_EXIT([&]() { wcChanges->releaseDefaultWriteConcernChange(); }); + + hangWhileSettingDefaultRWC.pauseWhileSet(); + auto& rwcDefaults = ReadWriteConcernDefaults::get(opCtx->getServiceContext()); auto newDefaults = rwcDefaults.generateNewCWRWCToBeSavedOnDisk( opCtx, request().getDefaultReadConcern(), request().getDefaultWriteConcern()); @@ -120,8 +135,7 @@ public: // because it only has to exist on the actual shards in order to be valid. if (serverGlobalParams.clusterRole != ClusterRole::ConfigServer) { if (auto optWC = newDefaults.getDefaultWriteConcern()) { - uassertStatusOK( - repl::ReplicationCoordinator::get(opCtx)->validateWriteConcern(*optWC)); + uassertStatusOK(replCoord->validateWriteConcern(*optWC)); } } diff --git a/src/mongo/db/repl/repl_set_config.cpp b/src/mongo/db/repl/repl_set_config.cpp index 86368756c7f..902435b53e0 100644 --- a/src/mongo/db/repl/repl_set_config.cpp +++ b/src/mongo/db/repl/repl_set_config.cpp @@ -766,6 +766,29 @@ ReplSetConfigPtr ReplSetConfig::getRecipientConfig() const { return _recipientConfig; } +bool ReplSetConfig::areWriteConcernModesTheSame(ReplSetConfig* otherConfig) const { + auto modeNames = getWriteConcernNames(); + auto otherModeNames = otherConfig->getWriteConcernNames(); + + if (modeNames.size() != otherModeNames.size()) { + return false; + } + + for (auto it = modeNames.begin(); it != modeNames.end(); it++) { + auto swPatternA = findCustomWriteMode(*it); + auto swPatternB = otherConfig->findCustomWriteMode(*it); + if (!swPatternA.isOK() || !swPatternB.isOK()) { + return false; + } + + if (swPatternA.getValue() != swPatternB.getValue()) { + return false; + } + } + + return true; +} + MemberConfig* MutableReplSetConfig::_findMemberByID(MemberId id) { for (auto it = getMembers().begin(); it != getMembers().end(); ++it) { if (it->getId() == id) { diff --git a/src/mongo/db/repl/repl_set_config.h b/src/mongo/db/repl/repl_set_config.h index 5e410b65963..847677cd292 100644 --- a/src/mongo/db/repl/repl_set_config.h +++ b/src/mongo/db/repl/repl_set_config.h @@ -552,6 +552,12 @@ public: */ ReplSetConfigPtr getRecipientConfig() const; + /** + * Compares the write concern modes with another config and returns 'true' if they are + * identical. + */ + bool areWriteConcernModesTheSame(ReplSetConfig* otherConfig) const; + private: /** * Sets replica set ID to 'defaultReplicaSetId' if 'cfg' does not contain an ID. diff --git a/src/mongo/db/repl/repl_set_config_test.cpp b/src/mongo/db/repl/repl_set_config_test.cpp index be6753afba4..e43bd0385c8 100644 --- a/src/mongo/db/repl/repl_set_config_test.cpp +++ b/src/mongo/db/repl/repl_set_config_test.cpp @@ -1931,6 +1931,193 @@ TEST(ReplSetConfig, MakeCustomWriteMode) { ASSERT_TRUE(swPattern.isOK()); } +TEST(ReplSetConfig, SameWriteConcernModesNoCustom) { + auto config = ReplSetConfig::parse(BSON("_id" + << "rs0" + << "version" << 1 << "term" << 1.0 << "protocolVersion" + << 1 << "members" + << BSON_ARRAY(BSON("_id" << 0 << "host" + << "localhost:12345")))); + + auto otherConfig = ReplSetConfig::parse(BSON("_id" + << "rs0" + << "version" << 2 << "term" << 1.0 + << "protocolVersion" << 1 << "members" + << BSON_ARRAY(BSON("_id" << 0 << "host" + << "localhost:6789")))); + + ASSERT(config.areWriteConcernModesTheSame(&otherConfig)); + ASSERT(otherConfig.areWriteConcernModesTheSame(&config)); +} + +TEST(ReplSetConfig, SameWriteConcernModesOneCustom) { + auto config = ReplSetConfig::parse( + BSON("_id" + << "rs0" + << "version" << 1 << "term" << 1.0 << "protocolVersion" << 1 << "members" + << BSON_ARRAY(BSON("_id" << 0 << "host" + << "localhost:12345" + << "tags" + << BSON("NYC" + << "NY"))) + << "settings" << BSON("getLastErrorModes" << BSON("eastCoast" << BSON("NYC" << 1))))); + + auto otherConfig = ReplSetConfig::parse( + BSON("_id" + << "rs0" + << "version" << 2 << "term" << 1.0 << "protocolVersion" << 1 << "members" + << BSON_ARRAY(BSON("_id" << 0 << "host" + << "localhost:6789" + << "tags" + << BSON("NYC" + << "NY"))) + << "settings" << BSON("getLastErrorModes" << BSON("eastCoast" << BSON("NYC" << 1))))); + + ASSERT(config.areWriteConcernModesTheSame(&otherConfig)); + ASSERT(otherConfig.areWriteConcernModesTheSame(&config)); +} + +TEST(ReplSetConfig, DifferentWriteConcernModesOneCustomDifferentName) { + auto config = ReplSetConfig::parse( + BSON("_id" + << "rs0" + << "version" << 1 << "term" << 1.0 << "protocolVersion" << 1 << "members" + << BSON_ARRAY(BSON("_id" << 0 << "host" + << "localhost:12345" + << "tags" + << BSON("NYC" + << "NY"))) + << "settings" << BSON("getLastErrorModes" << BSON("somename" << BSON("NYC" << 1))))); + + auto otherConfig = ReplSetConfig::parse( + BSON("_id" + << "rs0" + << "version" << 2 << "term" << 1.0 << "protocolVersion" << 1 << "members" + << BSON_ARRAY(BSON("_id" << 0 << "host" + << "localhost:6789" + << "tags" + << BSON("NYC" + << "NY"))) + << "settings" << BSON("getLastErrorModes" << BSON("othername" << BSON("NYC" << 1))))); + + ASSERT_FALSE(config.areWriteConcernModesTheSame(&otherConfig)); + ASSERT_FALSE(otherConfig.areWriteConcernModesTheSame(&config)); +} + +TEST(ReplSetConfig, DifferentWriteConcernModesOneCustomDifferentCounts) { + auto config = ReplSetConfig::parse( + BSON("_id" + << "rs0" + << "version" << 1 << "term" << 1.0 << "protocolVersion" << 1 << "members" + << BSON_ARRAY(BSON("_id" << 0 << "host" + << "localhost:12345" + << "tags" + << BSON("NYC" + << "NY")) + << BSON("_id" << 1 << "host" + << "otherhost:12345" + << "tags" + << BSON("NYC" + << "NY"))) + << "settings" << BSON("getLastErrorModes" << BSON("eastCoast" << BSON("NYC" << 1))))); + + auto otherConfig = ReplSetConfig::parse( + BSON("_id" + << "rs0" + << "version" << 1 << "term" << 1.0 << "protocolVersion" << 1 << "members" + << BSON_ARRAY(BSON("_id" << 0 << "host" + << "localhost:12345" + << "tags" + << BSON("NYC" + << "NY")) + << BSON("_id" << 1 << "host" + << "otherhost:12345" + << "tags" + << BSON("NYC" + << "NY"))) + << "settings" << BSON("getLastErrorModes" << BSON("eastCoast" << BSON("NYC" << 2))))); + + ASSERT_FALSE(config.areWriteConcernModesTheSame(&otherConfig)); + ASSERT_FALSE(otherConfig.areWriteConcernModesTheSame(&config)); +} + +TEST(ReplSetConfig, DifferentWriteConcernModesExtraTag) { + auto config = ReplSetConfig::parse(BSON("_id" + << "rs0" + << "version" << 1 << "term" << 1.0 << "protocolVersion" + << 1 << "members" + << BSON_ARRAY(BSON("_id" << 0 << "host" + << "localhost:12345" + << "tags" + << BSON("NYC" + << "NY")) + << BSON("_id" << 1 << "host" + << "otherhost:12345" + << "tags" + << BSON("Boston" + << "MA"))) + << "settings" + << BSON("getLastErrorModes" + << BSON("nyonly" << BSON("NYC" << 1) << "maonly" + << BSON("Boston" << 1))))); + + auto otherConfig = ReplSetConfig::parse( + BSON("_id" + << "rs0" + << "version" << 1 << "term" << 1.0 << "protocolVersion" << 1 << "members" + << BSON_ARRAY(BSON("_id" << 0 << "host" + << "localhost:12345" + << "tags" + << BSON("NYC" + << "NY")) + << BSON("_id" << 1 << "host" + << "otherhost:12345" + << "tags" + << BSON("Boston" + << "MA"))) + << "settings" << BSON("getLastErrorModes" << BSON("nyonly" << BSON("NYC" << 1))))); + + ASSERT_FALSE(config.areWriteConcernModesTheSame(&otherConfig)); + ASSERT_FALSE(otherConfig.areWriteConcernModesTheSame(&config)); +} + +TEST(ReplSetConfig, DifferentWriteConcernModesSameNameDifferentDefinition) { + auto config = ReplSetConfig::parse( + BSON("_id" + << "rs0" + << "version" << 1 << "term" << 1.0 << "protocolVersion" << 1 << "members" + << BSON_ARRAY(BSON("_id" << 0 << "host" + << "localhost:12345" + << "tags" + << BSON("NYC" + << "NY")) + << BSON("_id" << 1 << "host" + << "otherhost:12345" + << "tags" + << BSON("Boston" + << "MA"))) + << "settings" << BSON("getLastErrorModes" << BSON("eastCoast" << BSON("NYC" << 1))))); + + auto otherConfig = ReplSetConfig::parse(BSON( + "_id" + << "rs0" + << "version" << 1 << "term" << 1.0 << "protocolVersion" << 1 << "members" + << BSON_ARRAY(BSON("_id" << 0 << "host" + << "localhost:12345" + << "tags" + << BSON("NYC" + << "NY")) + << BSON("_id" << 1 << "host" + << "otherhost:12345" + << "tags" + << BSON("Boston" + << "MA"))) + << "settings" << BSON("getLastErrorModes" << BSON("eastCoast" << BSON("Boston" << 1))))); + + ASSERT_FALSE(config.areWriteConcernModesTheSame(&otherConfig)); + ASSERT_FALSE(otherConfig.areWriteConcernModesTheSame(&config)); +} + } // namespace } // namespace repl } // namespace mongo diff --git a/src/mongo/db/repl/repl_set_tag.h b/src/mongo/db/repl/repl_set_tag.h index 87dd68bd2ac..420ace32052 100644 --- a/src/mongo/db/repl/repl_set_tag.h +++ b/src/mongo/db/repl/repl_set_tag.h @@ -154,6 +154,37 @@ public: return _constraints.end(); } + /** + * Gets the number of constraints in this pattern. + */ + size_t getNumConstraints() const { + return _constraints.size(); + } + + bool operator==(const ReplSetTagPattern& other) const { + if (getNumConstraints() != other.getNumConstraints()) { + return false; + } + + for (auto itrA = constraintsBegin(); itrA != constraintsEnd(); itrA++) { + bool same = false; + for (auto itrB = other.constraintsBegin(); itrB != other.constraintsEnd(); itrB++) { + if (*itrA == *itrB) { + same = true; + break; + } + } + if (!same) { + return false; + } + } + return true; + } + + bool operator!=(const ReplSetTagPattern& other) const { + return !operator==(other); + } + private: std::vector<TagCountConstraint> _constraints; }; diff --git a/src/mongo/db/repl/replication_coordinator.h b/src/mongo/db/repl/replication_coordinator.h index 8cb3d976242..01966a7722a 100644 --- a/src/mongo/db/repl/replication_coordinator.h +++ b/src/mongo/db/repl/replication_coordinator.h @@ -1147,6 +1147,28 @@ public: */ virtual void recordIfCWWCIsSetOnConfigServerOnStartup(OperationContext* opCtx) = 0; + /** + * Interface used to synchronize changes to custom write concern tags in the config and + * custom default write concern settings. + * + * Use [reserve|release]DefaultWriteConcernChanges when making changes to the current + * default read/write concern. + * Use [reserve|release]ConfigWriteConcernTagChanges when executing a reconfig that + * could potentially change read/write concern tags. + */ + class WriteConcernTagChanges { + public: + WriteConcernTagChanges() = default; + virtual ~WriteConcernTagChanges() = default; + virtual bool reserveDefaultWriteConcernChange() = 0; + virtual void releaseDefaultWriteConcernChange() = 0; + + virtual bool reserveConfigWriteConcernTagChange() = 0; + virtual void releaseConfigWriteConcernTagChange() = 0; + }; + + virtual WriteConcernTagChanges* getWriteConcernTagChanges() = 0; + protected: ReplicationCoordinator(); }; diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp index 0805cb25fe1..23cae7e6c1a 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl.cpp @@ -149,6 +149,8 @@ MONGO_FAIL_POINT_DEFINE(hangAfterReconfig); MONGO_FAIL_POINT_DEFINE(skipBeforeFetchingConfig); // Hang after grabbing the RSTL but before we start rejecting writes. MONGO_FAIL_POINT_DEFINE(stepdownHangAfterGrabbingRSTL); +// Hang before making checks on the new config relative to the current one. +MONGO_FAIL_POINT_DEFINE(hangBeforeNewConfigValidationChecks); // Simulates returning a specified error in the hello response. MONGO_FAIL_POINT_DEFINE(setCustomErrorInHelloResponseMongoD); // Throws right before the call into recoverTenantMigrationAccessBlockers. @@ -3690,6 +3692,27 @@ Status ReplicationCoordinatorImpl::_doReplSetReconfig(OperationContext* opCtx, return status; ReplSetConfig newConfig = newConfigStatus.getValue(); + // Synchronize this change with potential changes to the default write concern. + auto wcChanges = getWriteConcernTagChanges(); + auto mustReleaseWCChange = false; + if (!oldConfig.areWriteConcernModesTheSame(&newConfig)) { + if (!wcChanges->reserveConfigWriteConcernTagChange()) { + return Status( + ErrorCodes::ConflictingOperationInProgress, + "Default write concern change(s) in progress. Please retry the reconfig later."); + } + // Reservation OK. + mustReleaseWCChange = true; + } + + ON_BLOCK_EXIT([&] { + if (mustReleaseWCChange) { + wcChanges->releaseConfigWriteConcernTagChange(); + } + }); + + hangBeforeNewConfigValidationChecks.pauseWhileSet(); + // Excluding reconfigs that bump the config term during step-up from checking against changing // the implicit default write concern, as it is not needed. if (!skipSafetyChecks /* skipping step-up reconfig */) { @@ -3740,6 +3763,30 @@ Status ReplicationCoordinatorImpl::_doReplSetReconfig(OperationContext* opCtx, } } } + + // If we are currently using a custom write concern as the default, check that the + // corresponding definition still exists in the new config. + if (serverGlobalParams.clusterRole == ClusterRole::None) { + try { + const auto rwcDefaults = + ReadWriteConcernDefaults::get(opCtx->getServiceContext()).getDefault(opCtx); + const auto wcDefault = rwcDefaults.getDefaultWriteConcern(); + if (wcDefault) { + auto validateWCStatus = newConfig.validateWriteConcern(wcDefault.get()); + if (!validateWCStatus.isOK()) { + return Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, + str::stream() << "May not remove custom write concern " + "definition from config while it is in " + "use as the default write concern. " + "Change the default write concern to a " + "non-conflicting setting and try the " + "reconfig again."); + } + } + } catch (const DBException& e) { + return e.toStatus("Exception while loading write concern default during reconfig"); + } + } } BSONObj oldConfigObj = oldConfig.toBSON(); @@ -6159,5 +6206,10 @@ void ReplicationCoordinatorImpl::_validateDefaultWriteConcernOnShardStartup(With } } +ReplicationCoordinatorImpl::WriteConcernTagChanges* +ReplicationCoordinatorImpl::getWriteConcernTagChanges() { + return &_writeConcernTagChanges; +} + } // namespace repl } // namespace mongo diff --git a/src/mongo/db/repl/replication_coordinator_impl.h b/src/mongo/db/repl/replication_coordinator_impl.h index 8affe603f30..4d24f253799 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.h +++ b/src/mongo/db/repl/replication_coordinator_impl.h @@ -518,6 +518,74 @@ public: */ void cancelElection_forTest(); + /** + * Implementation of an interface used to synchronize changes to custom write concern tags in + * the config and custom default write concern settings. + * See base class fore more information. + */ + class WriteConcernTagChangesImpl : public WriteConcernTagChanges { + public: + WriteConcernTagChangesImpl() = default; + virtual ~WriteConcernTagChangesImpl() = default; + + bool reserveDefaultWriteConcernChange() override { + stdx::lock_guard lock(_mutex); + if (_configWriteConcernTagChanges > 0) { + return false; + } + _defaultWriteConcernChanges++; + return true; + } + + void releaseDefaultWriteConcernChange() override { + stdx::lock_guard lock(_mutex); + invariant(_defaultWriteConcernChanges > 0); + _defaultWriteConcernChanges--; + } + + bool reserveConfigWriteConcernTagChange() override { + stdx::lock_guard lock(_mutex); + if (_defaultWriteConcernChanges > 0) { + return false; + } + _configWriteConcernTagChanges++; + return true; + } + + void releaseConfigWriteConcernTagChange() override { + stdx::lock_guard lock(_mutex); + invariant(_configWriteConcernTagChanges > 0); + _configWriteConcernTagChanges--; + } + + private: + // + // All member variables are labeled with one of the following codes indicating the + // synchronization rules for accessing them. + // + // (R) Read-only in concurrent operation; no synchronization required. + // (S) Self-synchronizing; access in any way from any context. + // (PS) Pointer is read-only in concurrent operation, item pointed to is self-synchronizing; + // Access in any context. + // (M) Reads and writes guarded by _mutex + // (I) Independently synchronized, see member variable comment. + + // The number of config write concern tag changes currently underway. + size_t _configWriteConcernTagChanges{0}; // (M) + + // The number of default write concern changes currently underway. + size_t _defaultWriteConcernChanges{0}; // (M) + + // Used to synchronize access to the above variables. + Mutex _mutex = MONGO_MAKE_LATCH( + "ReplicationCoordinatorImpl::PendingWriteConcernTagChangesImpl::_mutex"); // (S) + }; + + /** + * Returns a pointer to the WriteConcernTagChanges used by this instance. + */ + WriteConcernTagChanges* getWriteConcernTagChanges() override; + private: using CallbackFn = executor::TaskExecutor::CallbackFn; @@ -1766,6 +1834,10 @@ private: boost::optional<bool> _wasCWWCSetOnConfigServerOnStartup; InitialSyncerInterface::OnCompletionFn _onCompletion; + + // Construct used to synchronize default write concern changes with config write concern + // changes. + WriteConcernTagChangesImpl _writeConcernTagChanges; }; } // namespace repl diff --git a/src/mongo/db/repl/replication_coordinator_mock.cpp b/src/mongo/db/repl/replication_coordinator_mock.cpp index 0dfcd6e66e1..d396c2c429d 100644 --- a/src/mongo/db/repl/replication_coordinator_mock.cpp +++ b/src/mongo/db/repl/replication_coordinator_mock.cpp @@ -782,5 +782,11 @@ void ReplicationCoordinatorMock::recordIfCWWCIsSetOnConfigServerOnStartup(Operat MONGO_UNREACHABLE; } +ReplicationCoordinatorMock::WriteConcernTagChanges* +ReplicationCoordinatorMock::getWriteConcernTagChanges() { + MONGO_UNREACHABLE; + return nullptr; +} + } // namespace repl } // namespace mongo diff --git a/src/mongo/db/repl/replication_coordinator_mock.h b/src/mongo/db/repl/replication_coordinator_mock.h index a03227ce33e..a77d5ad4982 100644 --- a/src/mongo/db/repl/replication_coordinator_mock.h +++ b/src/mongo/db/repl/replication_coordinator_mock.h @@ -404,6 +404,21 @@ public: virtual void recordIfCWWCIsSetOnConfigServerOnStartup(OperationContext* opCtx) final; + class WriteConcernTagChangesMock : public WriteConcernTagChanges { + virtual ~WriteConcernTagChangesMock() = default; + virtual bool reserveDefaultWriteConcernChange() { + return false; + }; + virtual void releaseDefaultWriteConcernChange() {} + + virtual bool reserveConfigWriteConcernTagChange() { + return false; + }; + virtual void releaseConfigWriteConcernTagChange() {} + }; + + virtual WriteConcernTagChanges* getWriteConcernTagChanges() override; + private: ServiceContext* const _service; ReplSettings _settings; diff --git a/src/mongo/db/repl/replication_coordinator_noop.cpp b/src/mongo/db/repl/replication_coordinator_noop.cpp index 9ca8ffe1d9d..66f46c4fd92 100644 --- a/src/mongo/db/repl/replication_coordinator_noop.cpp +++ b/src/mongo/db/repl/replication_coordinator_noop.cpp @@ -607,5 +607,11 @@ void ReplicationCoordinatorNoOp::recordIfCWWCIsSetOnConfigServerOnStartup(Operat MONGO_UNREACHABLE; } +ReplicationCoordinatorNoOp::WriteConcernTagChanges* +ReplicationCoordinatorNoOp::getWriteConcernTagChanges() { + MONGO_UNREACHABLE; + return nullptr; +} + } // namespace repl } // namespace mongo diff --git a/src/mongo/db/repl/replication_coordinator_noop.h b/src/mongo/db/repl/replication_coordinator_noop.h index 635ac26d371..baf4b586d2b 100644 --- a/src/mongo/db/repl/replication_coordinator_noop.h +++ b/src/mongo/db/repl/replication_coordinator_noop.h @@ -332,6 +332,21 @@ public: virtual void recordIfCWWCIsSetOnConfigServerOnStartup(OperationContext* opCtx) final; + class WriteConcernTagChangesNoOp : public WriteConcernTagChanges { + virtual ~WriteConcernTagChangesNoOp() = default; + virtual bool reserveDefaultWriteConcernChange() { + return false; + }; + virtual void releaseDefaultWriteConcernChange() {} + + virtual bool reserveConfigWriteConcernTagChange() { + return false; + }; + virtual void releaseConfigWriteConcernTagChange() {} + }; + + virtual WriteConcernTagChanges* getWriteConcernTagChanges() override; + private: ServiceContext* const _service; }; diff --git a/src/mongo/embedded/replication_coordinator_embedded.cpp b/src/mongo/embedded/replication_coordinator_embedded.cpp index 53e95a0739c..d0182bfce59 100644 --- a/src/mongo/embedded/replication_coordinator_embedded.cpp +++ b/src/mongo/embedded/replication_coordinator_embedded.cpp @@ -636,5 +636,10 @@ void ReplicationCoordinatorEmbedded::recordIfCWWCIsSetOnConfigServerOnStartup( MONGO_UNREACHABLE; } +ReplicationCoordinatorEmbedded::WriteConcernTagChanges* +ReplicationCoordinatorEmbedded::getWriteConcernTagChanges() { + UASSERT_NOT_IMPLEMENTED; +} + } // namespace embedded } // namespace mongo diff --git a/src/mongo/embedded/replication_coordinator_embedded.h b/src/mongo/embedded/replication_coordinator_embedded.h index b6c5bfe1c62..f2d29ddea37 100644 --- a/src/mongo/embedded/replication_coordinator_embedded.h +++ b/src/mongo/embedded/replication_coordinator_embedded.h @@ -342,6 +342,21 @@ public: virtual void recordIfCWWCIsSetOnConfigServerOnStartup(OperationContext* opCtx) final; + class WriteConcernTagChangesEmbedded : public WriteConcernTagChanges { + virtual ~WriteConcernTagChangesEmbedded() = default; + virtual bool reserveDefaultWriteConcernChange() { + return false; + }; + virtual void releaseDefaultWriteConcernChange() {} + + virtual bool reserveConfigWriteConcernTagChange() { + return false; + }; + virtual void releaseConfigWriteConcernTagChange() {} + }; + + virtual WriteConcernTagChanges* getWriteConcernTagChanges() override; + private: // Back pointer to the ServiceContext that has started the instance. ServiceContext* const _service; |