diff options
Diffstat (limited to 'src/mongo/db/repl/replication_coordinator_impl.cpp')
-rw-r--r-- | src/mongo/db/repl/replication_coordinator_impl.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp index 560e2d61338..9da656c3138 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl.cpp @@ -42,6 +42,7 @@ #include "mongo/base/status.h" #include "mongo/client/fetcher.h" #include "mongo/db/audit.h" +#include "mongo/db/catalog/commit_quorum_options.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" #include "mongo/db/commands/test_commands_enabled.h" @@ -3118,6 +3119,51 @@ Status ReplicationCoordinatorImpl::_checkIfWriteConcernCanBeSatisfied_inlock( return _rsConfig.checkIfWriteConcernCanBeSatisfied(writeConcern); } +Status ReplicationCoordinatorImpl::checkIfCommitQuorumCanBeSatisfied( + const CommitQuorumOptions& commitQuorum) const { + stdx::lock_guard<stdx::mutex> lock(_mutex); + return _checkIfCommitQuorumCanBeSatisfied(lock, commitQuorum); +} + +Status ReplicationCoordinatorImpl::_checkIfCommitQuorumCanBeSatisfied( + WithLock, const CommitQuorumOptions& commitQuorum) const { + if (getReplicationMode() == modeNone) { + return Status(ErrorCodes::NoReplicationEnabled, + "No replication enabled when checking if commit quorum can be satisfied"); + } + + invariant(getReplicationMode() == modeReplSet); + + std::vector<MemberConfig> memberConfig(_rsConfig.membersBegin(), _rsConfig.membersEnd()); + + // We need to ensure that the 'commitQuorum' can be satisfied by all the members of this + // replica set. + bool commitQuorumCanBeSatisfied = + _topCoord->checkIfCommitQuorumCanBeSatisfied(commitQuorum, memberConfig); + if (!commitQuorumCanBeSatisfied) { + return Status(ErrorCodes::UnsatisfiableCommitQuorum, + str::stream() << "Commit quorum cannot be satisfied with the current replica " + << "set configuration"); + } + return Status::OK(); +} + +StatusWith<bool> ReplicationCoordinatorImpl::checkIfCommitQuorumIsSatisfied( + const CommitQuorumOptions& commitQuorum, + const std::vector<HostAndPort>& commitReadyMembers) const { + // If the 'commitQuorum' cannot be satisfied with all the members of this replica set, we + // need to inform the caller to avoid hanging while waiting for satisfiability of the + // 'commitQuorum' with 'commitReadyMembers' due to replica set reconfigurations. + stdx::lock_guard<stdx::mutex> lock(_mutex); + Status status = _checkIfCommitQuorumCanBeSatisfied(lock, commitQuorum); + if (!status.isOK()) { + return status; + } + + // Return whether or not the 'commitQuorum' is satisfied by the 'commitReadyMembers'. + return _topCoord->checkIfCommitQuorumIsSatisfied(commitQuorum, commitReadyMembers); +} + WriteConcernOptions ReplicationCoordinatorImpl::getGetLastErrorDefault() { stdx::lock_guard<stdx::mutex> lock(_mutex); if (_rsConfig.isInitialized()) { |