Status LegacyReplicationCoordinator::_stepDownHelper(OperationContext* txn, bool force, const Milliseconds& initialWaitTime, const Milliseconds& stepdownTime, const Milliseconds& postStepdownWaitTime) { invariant(getReplicationMode() == modeReplSet); if (!getCurrentMemberState().primary()) { return Status(ErrorCodes::NotMaster, "not primary so can't step down"); } if (!force) { Status status = _waitForSecondary(initialWaitTime, Milliseconds(10 * 1000)); if (!status.isOK()) { return status; } } // step down bool worked = repl::theReplSet->stepDown(txn, stepdownTime.total_seconds()); if (!worked) { return Status(ErrorCodes::NotMaster, "not primary so can't step down"); } if (postStepdownWaitTime.total_milliseconds() > 0) { log() << "waiting for secondaries to catch up" << endl; // The only caller of this with a non-zero postStepdownWaitTime is // stepDownAndWaitForSecondary, and the only caller of that is the shutdown command // which doesn't actually care if secondaries failed to catch up here, so we ignore the // return status of _waitForSecondary _waitForSecondary(postStepdownWaitTime, Milliseconds(0)); } return Status::OK(); }
bool ReplicationCoordinatorImpl::shouldIgnoreUniqueIndex(const IndexDescriptor* idx) { if (!idx->unique()) { return false; } // Never ignore _id index if (idx->isIdIndex()) { return false; } if (getReplicationMode() != modeReplSet) { return false; } // see SERVER-6671 MemberState ms = getCurrentMemberState(); if (! ((ms == MemberState::RS_STARTUP2) || (ms == MemberState::RS_RECOVERING) || (ms == MemberState::RS_ROLLBACK))) { return false; } // TODO(spencer): SERVER-14233 Remove support for old oplog versions, or move oplogVersion // into the repl coordinator /* // 2 is the oldest oplog version where operations // are fully idempotent. if (theReplSet->oplogVersion < 2) { return false; }*/ return true; }
Status LegacyReplicationCoordinator::canServeReadsFor(OperationContext* txn, const NamespaceString& ns, bool slaveOk) { if (txn->getClient()->isGod()) { return Status::OK(); } if (canAcceptWritesForDatabase(ns.db())) { return Status::OK(); } if (getReplicationMode() == modeMasterSlave && _settings.slave == SimpleSlave) { return Status::OK(); } if (slaveOk) { if (getReplicationMode() == modeMasterSlave || getReplicationMode() == modeNone) { return Status::OK(); } if (getCurrentMemberState().secondary()) { return Status::OK(); } return Status(ErrorCodes::NotMasterOrSecondaryCode, "not master or secondary; cannot currently read from this replSet member"); } return Status(ErrorCodes::NotMasterNoSlaveOkCode, "not master and slaveOk=false"); }
bool LegacyReplicationCoordinator::canAcceptWritesForDatabase(const StringData& dbName) { // we must check replSet since because getReplicationMode() isn't aware of modeReplSet // until theReplSet is initialized if (_settings.usingReplSets()) { if (theReplSet && getCurrentMemberState().primary()) { return true; } return dbName == "local"; } if (!_settings.slave) return true; // TODO(dannenberg) replAllDead is bad and should be removed when master slave is removed if (replAllDead) { return dbName == "local"; } if (_settings.master) { // if running with --master --slave, allow. return true; } return dbName == "local"; }
bool LegacyReplicationCoordinator::canAcceptWritesForDatabase(const StringData& dbName) { // we must check replSet since because getReplicationMode() isn't aware of modeReplSet // until theReplSet is initialized if (replSet) { if (theReplSet && getCurrentMemberState().primary()) { return true; } return dbName == "local"; } if (!replSettings.slave) return true; if (replAllDead) { return dbName == "local"; } if (replSettings.master) { // if running with --master --slave, allow. return true; } //TODO: Investigate if this is needed/used, see SERVER-9188 if (cc().isGod()) { return true; } return dbName == "local"; }
bool LegacyReplicationCoordinator::isMasterForReportingPurposes() { // we must check replSet since because getReplicationMode() isn't aware of modeReplSet // until theReplSet is initialized if (replSet) { if (theReplSet && getCurrentMemberState().primary()) { return true; } return false; } if (!replSettings.slave) return true; if (replAllDead) { return false; } if (replSettings.master) { // if running with --master --slave, allow. return true; } //TODO: Investigate if this is needed/used, see SERVER-9188 if (cc().isGod()) { return true; } return false; }
Status LegacyReplicationCoordinator::setLastOptime(const OID& rid, const OpTime& ts, const BSONObj& config) { std::string oplogNs = getReplicationMode() == modeReplSet? "local.oplog.rs" : "local.oplog.$main"; if (!updateSlaveTracking(BSON("_id" << rid), config, oplogNs, ts)) { return Status(ErrorCodes::NodeNotFound, str::stream() << "could not update node with _id: " << config["_id"].Int() << " beacuse it cannot be found in current ReplSetConfig"); } if (getReplicationMode() == modeReplSet && !getCurrentMemberState().primary()) { // pass along if we are not primary LOG(2) << "received notification that " << config << " has reached optime: " << ts.toStringPretty(); theReplSet->syncSourceFeedback.updateMap(rid, ts); } return Status::OK(); }
Status LegacyReplicationCoordinator::setLastOptime(OperationContext* txn, const OID& rid, const OpTime& ts) { { boost::lock_guard<boost::mutex> lock(_mutex); if (ts <= mapFindWithDefault(_slaveOpTimeMap, rid, OpTime())) { // Only update if ts is newer than what we have already return Status::OK(); } BSONObj config = mapFindWithDefault(_ridConfigMap, rid, BSONObj()); LOG(2) << "received notification that node with RID " << rid << " and config " << config << " has reached optime: " << ts.toStringPretty(); if (rid != getMyRID(txn)) { // TODO(spencer): Remove this invariant for backwards compatibility invariant(!config.isEmpty()); // This is what updates the progress information used for satisfying write concern // and wakes up threads waiting for replication. if (!updateSlaveTracking(BSON("_id" << rid), config, ts)) { return Status(ErrorCodes::NodeNotFound, str::stream() << "could not update node with _id: " << config["_id"].Int() << " because it cannot be found in current ReplSetConfig"); } } // This updates the _slaveOpTimeMap which is used for forwarding slave progress // upstream in chained replication. LOG(2) << "Updating our knowledge of the replication progress for node with RID " << rid << " to be at optime " << ts; _slaveOpTimeMap[rid] = ts; } if (getReplicationMode() == modeReplSet && !getCurrentMemberState().primary()) { // pass along if we are not primary theReplSet->syncSourceFeedback.forwardSlaveProgress(); } return Status::OK(); }
bool LegacyReplicationCoordinator::isMasterForReportingPurposes() { // we must check replSet since because getReplicationMode() isn't aware of modeReplSet // until theReplSet is initialized if (_settings.usingReplSets()) { if (theReplSet && getCurrentMemberState().primary()) { return true; } return false; } if (!_settings.slave) return true; if (replAllDead) { return false; } if (_settings.master) { // if running with --master --slave, allow. return true; } return false; }