void ReplicationCoordinatorExternalStateImpl::startThreads(const ReplSettings& settings) { stdx::lock_guard<stdx::mutex> lk(_threadMutex); if (_startedThreads) { return; } log() << "Starting replication storage threads"; if (settings.isMajorityReadConcernEnabled() || enableReplSnapshotThread) { _snapshotThread = SnapshotThread::start(getGlobalServiceContext()); } getGlobalServiceContext()->getGlobalStorageEngine()->setJournalListener(this); _writerPool = SyncTail::makeWriterPool(); _startedThreads = true; }
void ReplicationCoordinatorExternalStateImpl::startThreads(const ReplSettings& settings) { stdx::lock_guard<stdx::mutex> lk(_threadMutex); if (_startedThreads) { return; } log() << "Starting replication storage threads"; if (settings.isMajorityReadConcernEnabled() || enableReplSnapshotThread) { _snapshotThread = SnapshotThread::start(getGlobalServiceContext()); } getGlobalServiceContext()->getGlobalStorageEngine()->setJournalListener(this); _taskExecutor = stdx::make_unique<executor::ThreadPoolTaskExecutor>( makeThreadPool(), executor::makeNetworkInterface("NetworkInterfaceASIO-RS")); _taskExecutor->startup(); _writerPool = SyncTail::makeWriterPool(); _storageInterface->startup(); _startedThreads = true; }
void runSyncThread() { Client::initThread("rsSync"); AuthorizationSession::get(cc())->grantInternalAuthorization(); ReplicationCoordinator* replCoord = getGlobalReplicationCoordinator(); // Overwrite prefetch index mode in BackgroundSync if ReplSettings has a mode set. ReplSettings replSettings = replCoord->getSettings(); if (replSettings.isPrefetchIndexModeSet()) BackgroundSync::get()->setIndexPrefetchConfig(replSettings.getPrefetchIndexMode()); while (!inShutdown()) { // After a reconfig, we may not be in the replica set anymore, so // check that we are in the set (and not an arbiter) before // trying to sync with other replicas. // TODO(spencer): Use a condition variable to await loading a config if (replCoord->getMemberState().startup()) { warning() << "did not receive a valid config yet"; sleepsecs(1); continue; } const MemberState memberState = replCoord->getMemberState(); // An arbiter can never transition to any other state, and doesn't replicate, ever if (memberState.arbiter()) { break; } // If we are removed then we don't belong to the set anymore if (memberState.removed()) { sleepsecs(5); continue; } try { if (memberState.primary() && !replCoord->isWaitingForApplierToDrain()) { sleepsecs(1); continue; } bool initialSyncRequested = BackgroundSync::get()->getInitialSyncRequestedFlag(); // Check criteria for doing an initial sync: // 1. If the oplog is empty, do an initial sync // 2. If minValid has _initialSyncFlag set, do an initial sync // 3. If initialSyncRequested is true if (getGlobalReplicationCoordinator()->getMyLastOptime().isNull() || getInitialSyncFlag() || initialSyncRequested) { syncDoInitialSync(); continue; // start from top again in case sync failed. } if (!replCoord->setFollowerMode(MemberState::RS_RECOVERING)) { continue; } /* we have some data. continue tailing. */ SyncTail tail(BackgroundSync::get(), multiSyncApply); tail.oplogApplication(); } catch (...) { std::terminate(); } } }