diff options
Diffstat (limited to 'src')
4 files changed, 25 insertions, 11 deletions
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp index 64888f7fa89..e538718650c 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl.cpp @@ -320,7 +320,8 @@ ReplicationCoordinatorImpl::ReplicationCoordinatorImpl( _sleptLastElection(false), _canAcceptNonLocalWrites(!(settings.usingReplSets() || settings.isSlave())), _canServeNonLocalReads(0U), - _storage(storage) { + _storage(storage), + _random(prngSeed) { invariant(_service); @@ -336,7 +337,7 @@ ReplicationCoordinatorImpl::ReplicationCoordinatorImpl( _externalState->setupNoopWriter(kNoopWriterPeriod); } -ReplicationCoordinatorImpl::~ReplicationCoordinatorImpl() {} +ReplicationCoordinatorImpl::~ReplicationCoordinatorImpl() = default; void ReplicationCoordinatorImpl::waitForStartUpComplete_forTest() { _waitForStartUpComplete(); @@ -370,7 +371,8 @@ Date_t ReplicationCoordinatorImpl::getElectionTimeout_forTest() const { } Milliseconds ReplicationCoordinatorImpl::getRandomizedElectionOffset_forTest() { - return _getRandomizedElectionOffset(); + stdx::lock_guard<stdx::mutex> lk(_mutex); + return _getRandomizedElectionOffset_inlock(); } boost::optional<Date_t> ReplicationCoordinatorImpl::getPriorityTakeover_forTest() const { @@ -3786,5 +3788,9 @@ ReplicationCoordinatorImpl::_cancelElectionIfNeeded_inTopoLock() { return _electionFinishedEvent; } +int64_t ReplicationCoordinatorImpl::_nextRandomInt64_inlock(int64_t limit) { + return _random.nextInt64(limit); +} + } // 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 fd37c6a7a47..04c22e2e829 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.h +++ b/src/mongo/db/repl/replication_coordinator_impl.h @@ -49,6 +49,7 @@ #include "mongo/db/storage/snapshot_name.h" #include "mongo/executor/task_executor.h" #include "mongo/platform/atomic_word.h" +#include "mongo/platform/random.h" #include "mongo/platform/unordered_map.h" #include "mongo/platform/unordered_set.h" #include "mongo/stdx/condition_variable.h" @@ -808,7 +809,7 @@ private: * Return a randomized offset amount that is scaled in proportion to the size of the * _electionTimeoutPeriod. Used to add randomization to an election timeout. */ - Milliseconds _getRandomizedElectionOffset(); + Milliseconds _getRandomizedElectionOffset_inlock(); /** * Helper for _handleHeartbeatResponse. @@ -1233,6 +1234,11 @@ private: */ Status _waitUntilClusterTimeForRead(OperationContext* opCtx, LogicalTime clusterTime); + /** + * Returns a pseudorandom number no less than 0 and less than limit (which must be positive). + */ + int64_t _nextRandomInt64_inlock(int64_t limit); + // // All member variables are labeled with one of the following codes indicating the // synchronization rules for accessing them. @@ -1430,6 +1436,9 @@ private: // Cached copy of the current config protocol version. AtomicInt64 _protVersion; // (S) + // Source of random numbers used in setting election timeouts, etc. + PseudoRandom _random; // (M) + // This setting affects the Applier prefetcher behavior. mutable stdx::mutex _indexPrefetchMutex; ReplSettings::IndexPrefetchConfig _indexPrefetchConfig = diff --git a/src/mongo/db/repl/replication_coordinator_impl_elect.cpp b/src/mongo/db/repl/replication_coordinator_impl_elect.cpp index a1074150b03..be7d6ea79d7 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_elect.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_elect.cpp @@ -173,7 +173,7 @@ void ReplicationCoordinatorImpl::_onFreshnessCheckComplete() { break; case FreshnessChecker::FreshnessTie: if ((_selfIndex != 0) && !_sleptLastElection) { - const auto ms = Milliseconds(_replExecutor->nextRandomInt64(1000) + 50); + const auto ms = Milliseconds(_nextRandomInt64_inlock(1000) + 50); const Date_t nextCandidateTime = now + ms; log() << "possible election tie; sleeping " << ms << " until " << dateToISOStringLocal(nextCandidateTime); @@ -245,7 +245,7 @@ void ReplicationCoordinatorImpl::_onElectCmdRunnerComplete() { << " votes, but needed at least " << _rsConfig.getMajorityVoteCount(); // Suppress ourselves from standing for election again, giving other nodes a chance // to win their elections. - const auto ms = Milliseconds(_replExecutor->nextRandomInt64(1000) + 50); + const auto ms = Milliseconds(_nextRandomInt64_inlock(1000) + 50); const Date_t now(_replExecutor->now()); const Date_t nextCandidateTime = now + ms; log() << "waiting until " << nextCandidateTime << " before standing for election again"; diff --git a/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp b/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp index 68e1a61c4ac..99b39be285f 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp @@ -69,7 +69,7 @@ MONGO_FP_DECLARE(blockHeartbeatReconfigFinish); using executor::RemoteCommandRequest; -Milliseconds ReplicationCoordinatorImpl::_getRandomizedElectionOffset() { +Milliseconds ReplicationCoordinatorImpl::_getRandomizedElectionOffset_inlock() { long long electionTimeout = durationCount<Milliseconds>(_rsConfig.getElectionTimeoutPeriod()); long long randomOffsetUpperBound = electionTimeout * _externalState->getElectionTimeoutOffsetLimitFraction(); @@ -79,8 +79,7 @@ Milliseconds ReplicationCoordinatorImpl::_getRandomizedElectionOffset() { return Milliseconds(0); } - int64_t randomOffset = _replExecutor->nextRandomInt64(randomOffsetUpperBound); - return Milliseconds(randomOffset); + return Milliseconds{_nextRandomInt64_inlock(randomOffsetUpperBound)}; } void ReplicationCoordinatorImpl::_doMemberHeartbeat(executor::TaskExecutor::CallbackArgs cbData, @@ -302,7 +301,7 @@ stdx::unique_lock<stdx::mutex> ReplicationCoordinatorImpl::_handleHeartbeatRespo // Add randomized offset to calculated priority takeover delay. Milliseconds priorityTakeoverDelay = _rsConfig.getPriorityTakeoverDelay(_selfIndex); - Milliseconds randomOffset = _getRandomizedElectionOffset(); + Milliseconds randomOffset = _getRandomizedElectionOffset_inlock(); _priorityTakeoverWhen = _replExecutor->now() + priorityTakeoverDelay + randomOffset; log() << "Scheduling priority takeover at " << _priorityTakeoverWhen; _priorityTakeoverCbh = _scheduleWorkAt( @@ -827,7 +826,7 @@ void ReplicationCoordinatorImpl::_cancelAndRescheduleElectionTimeout_inlock() { return; } - Milliseconds randomOffset = _getRandomizedElectionOffset(); + Milliseconds randomOffset = _getRandomizedElectionOffset_inlock(); auto now = _replExecutor->now(); auto when = now + _rsConfig.getElectionTimeoutPeriod() + randomOffset; invariant(when > now); |