Beispiel #1
0
void NoopWriter::_writeNoop(OperationContext* opCtx) {
    // Use GlobalLock + lockMMAPV1Flush instead of DBLock to allow return when the lock is not
    // available. It may happen when the primary steps down and a shared global lock is acquired.
    Lock::GlobalLock lock(
        opCtx, MODE_IX, Date_t::now() + Milliseconds(1), Lock::InterruptBehavior::kLeaveUnlocked);
    if (!lock.isLocked()) {
        LOG(1) << "Global lock is not available skipping noopWrite";
        return;
    }
    opCtx->lockState()->lockMMAPV1Flush();

    auto replCoord = ReplicationCoordinator::get(opCtx);
    // Its a proxy for being a primary
    if (!replCoord->canAcceptWritesForDatabase(opCtx, "admin")) {
        LOG(1) << "Not a primary, skipping the noop write";
        return;
    }

    auto lastAppliedOpTime = replCoord->getMyLastAppliedOpTime();

    // _lastKnownOpTime is not protected by lock as its used only by one thread.
    if (lastAppliedOpTime != _lastKnownOpTime) {
        LOG(1) << "Not scheduling a noop write. Last known OpTime: " << _lastKnownOpTime
               << " != last primary OpTime: " << lastAppliedOpTime;
    } else {
        if (writePeriodicNoops.load()) {
            const auto logLevel = getTestCommandsEnabled() ? 0 : 1;
            LOG(logLevel)
                << "Writing noop to oplog as there has been no writes to this replica set in over "
                << _writeInterval;
            writeConflictRetry(
                opCtx, "writeNoop", NamespaceString::kRsOplogNamespace.ns(), [&opCtx] {
                    WriteUnitOfWork uow(opCtx);
                    opCtx->getClient()->getServiceContext()->getOpObserver()->onOpMessage(opCtx,
                                                                                          kMsgObj);
                    uow.commit();
                });
        }
    }

    _lastKnownOpTime = replCoord->getMyLastAppliedOpTime();
    LOG(1) << "Set last known op time to " << _lastKnownOpTime;
}
void ReplicationCoordinatorImpl::_recoverFromElectionTie(
    const ReplicationExecutor::CallbackArgs& cbData) {
    LockGuard topoLock(_topoMutex);

    auto now = _replExecutor.now();
    auto lastOpApplied = getMyLastAppliedOpTime();
    const auto status = _topCoord->checkShouldStandForElection(now, lastOpApplied);
    if (!status.isOK()) {
        LOG(2) << "ReplicationCoordinatorImpl::_recoverFromElectionTie -- " << status.reason();
    } else {
        fassertStatusOK(28817, _topCoord->becomeCandidateIfElectable(now, lastOpApplied, false));
        _startElectSelf();
    }
}
void ReplicationCoordinatorImpl::_startVoteRequester(long long newTerm) {
    invariant(_voteRequester);
    LoseElectionGuardV1 lossGuard(this);

    LockGuard lk(_topoMutex);

    const auto lastOpTime =
        _isDurableStorageEngine() ? getMyLastDurableOpTime() : getMyLastAppliedOpTime();

    _voteRequester.reset(new VoteRequester);
    StatusWith<ReplicationExecutor::EventHandle> nextPhaseEvh = _voteRequester->start(
        &_replExecutor, _rsConfig, _selfIndex, _topCoord->getTerm(), false, lastOpTime);
    if (nextPhaseEvh.getStatus() == ErrorCodes::ShutdownInProgress) {
        return;
    }
    fassert(28643, nextPhaseEvh.getStatus());
    _replExecutor.onEvent(
        nextPhaseEvh.getValue(),
        stdx::bind(&ReplicationCoordinatorImpl::_onVoteRequestComplete, this, newTerm));

    lossGuard.dismiss();
}