void LegacyReplicationCoordinator::prepareReplSetUpdatePositionCommandHandshakes(
            OperationContext* txn,
            std::vector<BSONObj>* handshakes) {
        invariant(getReplicationMode() == modeReplSet);
        boost::lock_guard<boost::mutex> lock(_mutex);
        // handshake obj for us
        BSONObjBuilder cmd;
        cmd.append("replSetUpdatePosition", 1);
        BSONObjBuilder sub (cmd.subobjStart("handshake"));
        sub.append("handshake", getMyRID(txn));
        sub.append("member", theReplSet->selfId());
        sub.append("config", theReplSet->myConfig().asBson());
        sub.doneFast();
        handshakes->push_back(cmd.obj());

        // handshake objs for all chained members
        for (OIDMemberMap::const_iterator itr = _ridMemberMap.begin();
             itr != _ridMemberMap.end(); ++itr) {
            BSONObjBuilder cmd;
            cmd.append("replSetUpdatePosition", 1);
            // outer handshake indicates this is a handshake command
            // inner is needed as part of the structure to be passed to gotHandshake
            BSONObjBuilder subCmd (cmd.subobjStart("handshake"));
            subCmd.append("handshake", itr->first);
            subCmd.append("member", itr->second->id());
            subCmd.append("config", itr->second->config().asBson());
            subCmd.doneFast();
            handshakes->push_back(cmd.obj());
        }
    }
 void LegacyReplicationCoordinator::prepareReplSetUpdatePositionCommand(
         OperationContext* txn,
         BSONObjBuilder* cmdBuilder) {
     invariant(getReplicationMode() == modeReplSet);
     boost::lock_guard<boost::mutex> lock(_mutex);
     cmdBuilder->append("replSetUpdatePosition", 1);
     // create an array containing objects each member connected to us and for ourself
     BSONArrayBuilder arrayBuilder(cmdBuilder->subarrayStart("optimes"));
     OID myID = getMyRID(txn);
     {
         for (SlaveOpTimeMap::const_iterator itr = _slaveOpTimeMap.begin();
                 itr != _slaveOpTimeMap.end(); ++itr) {
             const OID& rid = itr->first;
             const BSONObj& config = mapFindWithDefault(_ridConfigMap, rid, BSONObj());
             BSONObjBuilder entry(arrayBuilder.subobjStart());
             entry.append("_id", rid);
             entry.append("optime", itr->second);
             // SERVER-14550 Even though the "config" field isn't used on the other end in 2.8,
             // we need to keep sending it for 2.6 compatibility.
             // TODO(spencer): Remove this after 2.8 is released.
             if (rid == myID) {
                 entry.append("config", theReplSet->myConfig().asBson());
             }
             else {
                 entry.append("config", config);
             }
         }
     }
 }
    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();
    }
Example #4
0
    void ReplicationCoordinatorImpl::prepareReplSetUpdatePositionCommandHandshakes(
            OperationContext* txn,
            std::vector<BSONObj>* handshakes) {
        boost::lock_guard<boost::mutex> lock(_mutex);
        // handshake obj for us
        BSONObjBuilder cmd;
        cmd.append("replSetUpdatePosition", 1);
        {
            BSONObjBuilder sub (cmd.subobjStart("handshake"));
            sub.append("handshake", getMyRID(txn));
            sub.append("member", _thisMembersConfigIndex);
            // SERVER-14550 Even though the "config" field isn't used on the other end in 2.8,
            // we need to keep sending it for 2.6 compatibility.
            // TODO(spencer): Remove this after 2.8 is released.
            sub.append("config", _rsConfig.getMemberAt(_thisMembersConfigIndex).toBSON(
                    _rsConfig.getTagConfig()));
        }
        handshakes->push_back(cmd.obj());

        // handshake objs for all chained members
        for (SlaveInfoMap::const_iterator itr = _slaveInfoMap.begin();
             itr != _slaveInfoMap.end(); ++itr) {
            BSONObjBuilder cmd;
            cmd.append("replSetUpdatePosition", 1);
            {
                BSONObjBuilder subCmd (cmd.subobjStart("handshake"));
                subCmd.append("handshake", itr->first);
                int memberID = itr->second.memberID;
                subCmd.append("member", memberID);
                // SERVER-14550 Even though the "config" field isn't used on the other end in 2.8,
                // we need to keep sending it for 2.6 compatibility.
                // TODO(spencer): Remove this after 2.8 is released.
                subCmd.append("config",
                              _rsConfig.getMemberAt(memberID).toBSON(_rsConfig.getTagConfig()));
            }
            handshakes->push_back(cmd.obj());
        }
    }
Example #5
0
 OpTime ReplicationCoordinatorImpl::_getLastOpApplied() {
     boost::lock_guard<boost::mutex> lk(_mutex);
     OperationContextNoop txn;
     return _slaveInfoMap[getMyRID(&txn)].opTime;
 }