Esempio n. 1
0
mxArray *GetTick(mxArray *inst, mxArray *start, mxArray *end)
{
    mxArray *result;
    const char *field_names[] = {"tradingday", "time", "instrument", "o", "h", "l", "c", "v", "i", "a1", "b1", "av1", "bv1"};
    
    string instrument = mxArrayToString(inst);
    int st = mxGetScalar(start);
    int et = mxGetScalar(end);
    auto_ptr<DBClientCursor> cursor;
    BSONObjBuilder b;
    BSONObjBuilder timePeriod;
    
    b.append("InstrumentID", instrument);
    timePeriod.appendDate("$gte",( (st - 719529) * 24LL)* 60LL * 60LL * 1000LL);
    timePeriod.appendDate("$lte", ( (et - 719529 + 1) * 24LL) * 60LL * 60LL * 1000LL);
    b.append("UpdateTime", timePeriod.obj());
    BSONObj qry = b.obj();
    cursor = mCon->query(string("MarketData.") + collection, qry);
    int size = cursor->itcount();
//     mexPrintf("数据长度%d, collection为%s\n", size, collection.c_str());
    mwSize dims[2] = {1, size};
    result = mxCreateStructArray(2, dims, sizeof(field_names)/sizeof(*field_names), field_names);
    cursor = mCon->query(string("MarketData.") + collection, qry);
    BSONObj p;
    int i = size - 1;
    while(cursor->more())
    {
        p = cursor->next();
        tm buf;
        //trun into peking time;
        Date_t pkTime = Date_t(p["UpdateTime"].Date().millis + 8 * 3600000LL);
        double time = pkTime.millis%1000 / 100 / 100000.0;
        pkTime.toTm(&buf);
        int day = (buf.tm_year + 1900) * 10000 + (buf.tm_mon + 1) * 100 + buf.tm_mday;
        time = time + buf.tm_hour + buf.tm_min / 100.0 + buf.tm_sec / 10000.0;
        
        mxSetField(result, i, "tradingday", mxCreateDoubleScalar(day));
        mxSetField(result, i, "time", mxCreateDoubleScalar(time));
        mxSetField(result, i, "instrument", mxCreateString(instrument.c_str()));
        mxSetField(result, i, "o", mxCreateDoubleScalar( p["OpenPrice"].Double() ));
        mxSetField(result, i, "h", mxCreateDoubleScalar(p["HighestPrice"].Double()));
        mxSetField(result, i, "l", mxCreateDoubleScalar(p["LowestPrice"].Double()));
        mxSetField(result, i, "c", mxCreateDoubleScalar(p["LastPrice"].Double()));
        mxSetField(result, i, "v", mxCreateDoubleScalar(p["Volume"].Int()));
        mxSetField(result, i, "i", mxCreateDoubleScalar(p["OpenInterest"].Double()));
        mxSetField(result, i, "a1", mxCreateDoubleScalar(p["AskPrice1"].Double()));
        mxSetField(result, i, "b1", mxCreateDoubleScalar(p["BidPrice1"].Double()));
        mxSetField(result, i, "av1", mxCreateDoubleScalar(p["AskVolume1"].Int()));
        mxSetField(result, i, "bv1", mxCreateDoubleScalar(p["BidVolume1"].Int()));
        
        --i;
        if(i < -1)
        {
            mexWarnMsgTxt("GetTick程序越界!");
            break;
        }
    }
    
    return result;
}
Esempio n. 2
0
    void ReplSetImpl::_summarizeStatus(BSONObjBuilder& b) const {
        vector<BSONObj> v;

        const Member *_self = this->_self;
        assert( _self );

        // add self
        {
            BSONObjBuilder bb;
            bb.append("_id", (int) _self->id());
            bb.append("name", _self->fullName());
            bb.append("health", 1.0);
            bb.append("state", (int) box.getState().s);
            bb.append("stateStr", box.getState().toString());
            bb.appendTimestamp("optime", lastOpTimeWritten.asDate());
            bb.appendDate("optimeDate", lastOpTimeWritten.getSecs() * 1000LL);
            string s = _self->lhb();
            if( !s.empty() )
                bb.append("errmsg", s);
            bb.append("self", true);
            v.push_back(bb.obj());
        }

        Member *m =_members.head();
        while( m ) {
            BSONObjBuilder bb;
            bb.append("_id", (int) m->id());
            bb.append("name", m->fullName());
            double h = m->hbinfo().health;
            bb.append("health", h);
            bb.append("state", (int) m->state().s);
            if( h == 0 ) {
                // if we can't connect the state info is from the past and could be confusing to show
                bb.append("stateStr", "(not reachable/healthy)");
            }
            else {
                bb.append("stateStr", m->state().toString());
            }
            bb.append("uptime", (unsigned) (m->hbinfo().upSince ? (time(0)-m->hbinfo().upSince) : 0));
            bb.appendTimestamp("optime", m->hbinfo().opTime.asDate());
            bb.appendDate("optimeDate", m->hbinfo().opTime.getSecs() * 1000LL);
            bb.appendTimeT("lastHeartbeat", m->hbinfo().lastHeartbeat);
            bb.append("ping", m->hbinfo().ping);
            string s = m->lhb();
            if( !s.empty() )
                bb.append("errmsg", s);
            v.push_back(bb.obj());
            m = m->next();
        }
        sort(v.begin(), v.end());
        b.append("set", name());
        b.appendTimeT("date", time(0));
        b.append("myState", box.getState().s);
        if (_currentSyncTarget) {
            b.append("syncingTo", _currentSyncTarget->fullName());
        }
        b.append("members", v);
        if( replSetBlind )
            b.append("blind",true); // to avoid confusion if set...normally never set except for testing.
    }
BSONObj CollectionBulkLoaderImpl::Stats::toBSON() const {
    BSONObjBuilder bob;
    bob.appendDate("startBuildingIndexes", startBuildingIndexes);
    bob.appendDate("endBuildingIndexes", endBuildingIndexes);
    auto indexElapsed = endBuildingIndexes - startBuildingIndexes;
    long long indexElapsedMillis = duration_cast<Milliseconds>(indexElapsed).count();
    bob.appendNumber("indexElapsedMillis", indexElapsedMillis);
    return bob.obj();
}
Esempio n. 4
0
BSONObj DatabaseCloner::Stats::toBSON() const {
    BSONObjBuilder bob;
    bob.appendNumber("collections", collections);
    bob.appendNumber("clonedCollections", clonedCollections);
    bob.appendDate("start", start);
    bob.appendDate("end", end);
    auto elapsed = end - start;
    long long elapsedMillis = duration_cast<Milliseconds>(elapsed).count();
    bob.appendNumber("elapsedMillis", elapsedMillis);
    return bob.obj();
}
Esempio n. 5
0
BSONObj CollectionCloner::Stats::toBSON() const {
    BSONObjBuilder bob;
    bob.appendNumber("documents", documents);
    bob.appendNumber("indexes", indexes);
    bob.appendNumber("fetchedBatches", fetchBatches);
    bob.appendDate("start", start);
    bob.appendDate("end", end);
    auto elapsed = end - start;
    long long elapsedMillis = duration_cast<Milliseconds>(elapsed).count();
    bob.appendNumber("elapsedMillis", elapsedMillis);
    return bob.obj();
}
Esempio n. 6
0
    virtual bool run(OperationContext* txn,
                     const string&,
                     BSONObj& cmdObj,
                     int,
                     string& errmsg,
                     BSONObjBuilder& result) {
        /* currently request to arbiter is (somewhat arbitrarily) an ismaster request that is not
           authenticated.
        */
        if (cmdObj["forShell"].trueValue())
            LastError::get(txn->getClient()).disable();

        appendReplicationInfo(txn, result, 0);

        if (serverGlobalParams.configsvrMode == ServerGlobalParams::ConfigServerMode::CSRS) {
            result.append("configsvr", 1);
        }

        result.appendNumber("maxBsonObjectSize", BSONObjMaxUserSize);
        result.appendNumber("maxMessageSizeBytes", MaxMessageSizeBytes);
        result.appendNumber("maxWriteBatchSize", BatchedCommandRequest::kMaxWriteBatchSize);
        result.appendDate("localTime", jsTime());
        result.append("maxWireVersion", maxWireVersion);
        result.append("minWireVersion", minWireVersion);
        return true;
    }
    // Produce a reply to a RAFT-style RequestVote RPC; this is MongoDB ReplSetFresh command
    // The caller should validate that the message is for the correct set, and has the required data
    void TopologyCoordinatorImpl::prepareRequestVoteResponse(const Date_t now,
                                                             const BSONObj& cmdObj,
                                                             const OpTime& lastOpApplied,
                                                             std::string& errmsg,
                                                             BSONObjBuilder& result) {

        string who = cmdObj["who"].String();
        int cfgver = cmdObj["cfgver"].Int();
        OpTime opTime(cmdObj["opTime"].Date());

        bool weAreFresher = false;
        if( _currentConfig.getConfigVersion() > cfgver ) {
            log() << "replSet member " << who << " is not yet aware its cfg version "
                  << cfgver << " is stale";
            result.append("info", "config version stale");
            weAreFresher = true;
        }
        // check not only our own optime, but any other member we can reach
        else if( opTime < _commitOkayThrough ||
                 opTime < _latestKnownOpTime())  {
            weAreFresher = true;
        }
        result.appendDate("opTime", lastOpApplied.asDate());
        result.append("fresher", weAreFresher);

        bool doVeto = _shouldVeto(cmdObj, errmsg);
        result.append("veto",doVeto);
        if (doVeto) {
            result.append("errmsg", errmsg);
        }
    }
Esempio n. 8
0
BSONObj createBSONMetadataDocument(const BSONObj& metadata, Date_t date) {
    BSONObjBuilder builder;
    builder.appendDate(kFTDCIdField, date);
    builder.appendNumber(kFTDCTypeField, static_cast<int>(FTDCType::kMetadata));
    builder.appendObject(kFTDCDocField, metadata.objdata(), metadata.objsize());

    return builder.obj();
}
Esempio n. 9
0
BSONObj createBSONMetricChunkDocument(ConstDataRange buf, Date_t date) {
    BSONObjBuilder builder;

    builder.appendDate(kFTDCIdField, date);
    builder.appendNumber(kFTDCTypeField, static_cast<int>(FTDCType::kMetricChunk));
    builder.appendBinData(kFTDCDataField, buf.length(), BinDataType::BinDataGeneral, buf.data());

    return builder.obj();
}
DocumentSource::GetNextResult DocumentSourceCollStats::getNext() {
    pExpCtx->checkForInterrupt();

    if (_finished) {
        return GetNextResult::makeEOF();
    }

    _finished = true;

    BSONObjBuilder builder;

    builder.append("ns", pExpCtx->ns.ns());

    auto shardName = _mongod->getShardName(pExpCtx->opCtx);

    if (!shardName.empty()) {
        builder.append("shard", shardName);
    }

    builder.append("host", getHostNameCachedAndPort());
    builder.appendDate("localTime", jsTime());

    if (_collStatsSpec.hasField("latencyStats")) {
        // If the latencyStats field exists, it must have been validated as an object when parsing.
        bool includeHistograms = false;
        if (_collStatsSpec["latencyStats"].type() == BSONType::Object) {
            includeHistograms = _collStatsSpec["latencyStats"]["histograms"].boolean();
        }
        _mongod->appendLatencyStats(pExpCtx->ns, includeHistograms, &builder);
    }

    if (_collStatsSpec.hasField("storageStats")) {
        // If the storageStats field exists, it must have been validated as an object when parsing.
        BSONObjBuilder storageBuilder(builder.subobjStart("storageStats"));
        Status status = _mongod->appendStorageStats(
            pExpCtx->ns, _collStatsSpec["storageStats"].Obj(), &storageBuilder);
        storageBuilder.doneFast();
        if (!status.isOK()) {
            uasserted(40280,
                      str::stream() << "Unable to retrieve storageStats in $collStats stage: "
                                    << status.reason());
        }
    }

    if (_collStatsSpec.hasField("count")) {
        Status status = _mongod->appendRecordCount(pExpCtx->ns, &builder);
        if (!status.isOK()) {
            uasserted(40481,
                      str::stream() << "Unable to retrieve count in $collStats stage: "
                                    << status.reason());
        }
    }

    return {Document(builder.obj())};
}
Esempio n. 11
0
    void Chunk::serialize(BSONObjBuilder& to){
        if ( _lastmod )
            to.appendDate( "lastmod" , _lastmod );
        else 
            to.appendTimestamp( "lastmod" );

        to << "ns" << _ns;
        to << "min" << _min;
        to << "max" << _max;
        to << "shard" << _shard;
    }
Esempio n. 12
0
 void logTransactionOpsRef(GTID gtid, uint64_t timestamp, uint64_t hash, OID& oid) {
     Lock::DBRead lk1("local");
     BSONObjBuilder b;
     addGTIDToBSON("_id", gtid, b);
     b.appendDate("ts", timestamp);
     b.append("h", (long long)hash);
     b.append("a", true);
     b.append("ref", oid);
     BSONObj bb = b.done();
     writeEntryToOplog(bb, true);
 }
Esempio n. 13
0
        virtual bool run(const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool /*fromRepl*/) {
            /* currently request to arbiter is (somewhat arbitrarily) an ismaster request that is not
               authenticated.
            */
            appendReplicationInfo(result, 0);

            result.appendNumber("maxBsonObjectSize", BSONObjMaxUserSize);
            result.appendNumber("maxMessageSizeBytes", MaxMessageSizeBytes);
            result.appendDate("localTime", jsTime());
            return true;
        }
Esempio n. 14
0
        void run(){
            Scope * s = globalScriptEngine->createScope();
            
            { // date
                BSONObj o;
                { 
                    BSONObjBuilder b;
                    b.appendDate( "d" , 123456789 );
                    o = b.obj();
                }
                s->setObject( "x" , o );
                
                s->invoke( "return x.d.getTime() != 12;" , BSONObj() );
                ASSERT_EQUALS( true, s->getBoolean( "return" ) );
                
                s->invoke( "z = x.d.getTime();" , BSONObj() );
                ASSERT_EQUALS( 123456789 , s->getNumber( "z" ) );
                
                s->invoke( "z = { z : x.d }" , BSONObj() );
                BSONObj out = s->getObject( "z" );
                ASSERT( out["z"].type() == Date );
            }

            { // regex
                BSONObj o;
                { 
                    BSONObjBuilder b;
                    b.appendRegex( "r" , "^a" , "i" );
                    o = b.obj();
                }
                s->setObject( "x" , o );
                
                s->invoke( "z = x.r.test( 'b' );" , BSONObj() );
                ASSERT_EQUALS( false , s->getBoolean( "z" ) );

                s->invoke( "z = x.r.test( 'a' );" , BSONObj() );
                ASSERT_EQUALS( true , s->getBoolean( "z" ) );

                s->invoke( "z = x.r.test( 'ba' );" , BSONObj() );
                ASSERT_EQUALS( false , s->getBoolean( "z" ) );

                s->invoke( "z = { a : x.r };" , BSONObj() );

                BSONObj out = s->getObject("z");
                ASSERT_EQUALS( (string)"^a" , out["a"].regex() );
                ASSERT_EQUALS( (string)"i" , out["a"].regexFlags() );

            }
            
            delete s;
        }
Esempio n. 15
0
    static void _logTransactionOps(GTID gtid, uint64_t timestamp, uint64_t hash, BSONArray& opInfo) {
        Lock::DBRead lk1("local");

        BSONObjBuilder b;
        addGTIDToBSON("_id", gtid, b);
        b.appendDate("ts", timestamp);
        b.append("h", (long long)hash);
        b.append("a", true);
        b.append("ops", opInfo);

        BSONObj bb = b.done();
        // write it to oplog
        LOG(3) << "writing " << bb.toString(false, true) << " to master " << endl;
        writeEntryToOplog(bb, true);
    }
Esempio n. 16
0
        virtual bool run(const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool /*fromRepl*/) {
            /* currently request to arbiter is (somewhat arbitrarily) an ismaster request that is not
               authenticated.
            */
            if ( cmdObj["forShell"].trueValue() )
                lastError.disableForCommand();

            appendReplicationInfo(result, 0);

            result.appendNumber("maxBsonObjectSize", BSONObjMaxUserSize);
            result.appendNumber("maxMessageSizeBytes", MaxMessageSizeBytes);
            result.appendDate("localTime", jsTime());
            result.append("maxWireVersion", maxWireVersion);
            result.append("minWireVersion", minWireVersion);
            return true;
        }
Esempio n. 17
0
    void DBConfig::CollectionInfo::save( const string& ns , DBClientBase* conn ) {
        BSONObj key = BSON( "_id" << ns );

        BSONObjBuilder val;
        val.append( "_id" , ns );
        val.appendDate( "lastmod" , time(0) );
        val.appendBool( "dropped" , _dropped );
        if ( _cm )
            _cm->getInfo( val );

        conn->update( ShardNS::collection , key , val.obj() , true );
        string err = conn->getLastError();
        uassert( 13473 , (string)"failed to save collection (" + ns + "): " + err , err.size() == 0 );

        _dirty = false;
    }
Esempio n. 18
0
 void Scope::append( BSONObjBuilder & builder , const char * fieldName , const char * scopeName ){
     int t = type( scopeName );
     
     switch ( t ){
     case Object:
         builder.append( fieldName , getObject( scopeName ) );
         break;
     case Array:
         builder.appendArray( fieldName , getObject( scopeName ) );
         break;
     case NumberDouble:
         builder.append( fieldName , getNumber( scopeName ) );
         break;
     case NumberInt:
         builder.append( fieldName , getNumberInt( scopeName ) );
         break;
     case NumberLong:
         builder.append( fieldName , getNumberLongLong( scopeName ) );
         break;
     case String:
         builder.append( fieldName , getString( scopeName ).c_str() );
         break;
     case Bool:
         builder.appendBool( fieldName , getBoolean( scopeName ) );
         break;
     case jstNULL:
     case Undefined:
         builder.appendNull( fieldName );
         break;
     case Date:
         // TODO: make signed
         builder.appendDate( fieldName , Date_t((unsigned long long)getNumber( scopeName )) );
         break;
     case Code:
         builder.appendCode( fieldName , getString( scopeName ) );
         break;
     default:
         stringstream temp;
         temp << "can't append type from:";
         temp << t;
         uassert( 10206 ,  temp.str() , 0 );
     }
     
 }
Esempio n. 19
0
void Scope::append(BSONObjBuilder& builder, const char* fieldName, const char* scopeName) {
    int t = type(scopeName);
    switch (t) {
    case Object:
        builder.append(fieldName, getObject(scopeName));
        break;
    case Array:
        builder.appendArray(fieldName, getObject(scopeName));
        break;
    case NumberDouble:
        builder.append(fieldName, getNumber(scopeName));
        break;
    case NumberInt:
        builder.append(fieldName, getNumberInt(scopeName));
        break;
    case NumberLong:
        builder.append(fieldName, getNumberLongLong(scopeName));
        break;
    case NumberDecimal:
        builder.append(fieldName, getNumberDecimal(scopeName));
        break;
    case String:
        builder.append(fieldName, getString(scopeName));
        break;
    case Bool:
        builder.appendBool(fieldName, getBoolean(scopeName));
        break;
    case jstNULL:
    case Undefined:
        builder.appendNull(fieldName);
        break;
    case Date:
        builder.appendDate(
            fieldName,
            Date_t::fromMillisSinceEpoch(static_cast<long long>(getNumber(scopeName))));
        break;
    case Code:
        builder.appendCode(fieldName, getString(scopeName));
        break;
    default:
        uassert(10206, str::stream() << "can't append type from: " << t, 0);
    }
}
Esempio n. 20
0
 virtual bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
     string fromhost = cmdObj.getStringField("from");
     if ( fromhost.empty() ) {
         errmsg = "missing from spec";
         return false;
     }
     string collection = cmdObj.getStringField("startCloneCollection");
     if ( collection.empty() ) {
         errmsg = "missing startCloneCollection spec";
         return false;
     }
     BSONObj query = cmdObj.getObjectField("query");
     if ( query.isEmpty() )
         query = BSONObj();
     BSONElement copyIndexesSpec = cmdObj.getField("copyindexes");
     bool copyIndexes = copyIndexesSpec.isBoolean() ? copyIndexesSpec.boolean() : true;
     // Will not be used if doesn't exist.
     int logSizeMb = cmdObj.getIntField( "logSizeMb" );
     
     /* replication note: we must logOp() not the command, but the cloned data -- if the slave
      were to clone it would get a different point-in-time and not match.
      */
     setClient( collection.c_str() );
     
     log() << "startCloneCollection.  db:" << ns << " collection:" << collection << " from: " << fromhost << " query: " << query << endl;
     
     Cloner c;
     long long cursorId;
     bool res = c.startCloneCollection( fromhost.c_str(), collection.c_str(), query, errmsg, !fromRepl, copyIndexes, logSizeMb, cursorId );
     
     if ( res ) {
         BSONObjBuilder b;
         b << "fromhost" << fromhost;
         b << "collection" << collection;
         b << "query" << query;
         b.appendDate( "cursorId", cursorId );
         BSONObj token = b.done();
         result << "finishToken" << token;
     }
     return res;
 }
Esempio n. 21
0
    bool appendSpecialDBObject( Convertor * c , BSONObjBuilder& b , const string& name , JSObject * o ){

        if ( JS_InstanceOf( c->_context , o , &object_id_class , 0 ) ){
            OID oid;
            oid.init( c->getString( o , "str" ) );
            b.append( name.c_str() , oid );
            return true;
        }

        if ( JS_InstanceOf( c->_context , o , &minkey_class , 0 ) ){
            b.appendMinKey( name.c_str() );
            return true;
        }

        if ( JS_InstanceOf( c->_context , o , &maxkey_class , 0 ) ){
            b.appendMaxKey( name.c_str() );
            return true;
        }
        
        if ( JS_InstanceOf( c->_context , o , &timestamp_class , 0 ) ){
            b.appendTimestamp( name.c_str() , (unsigned long long)c->getNumber( o , "t" ) , (unsigned int )c->getNumber( o , "i" ) );
            return true;
        }
        
        {
            jsdouble d = js_DateGetMsecSinceEpoch( c->_context , o );
            if ( d ){
                b.appendDate( name.c_str() , (unsigned long long)d );
                return true;
            }
        }
        
        

        return false;
    }
Esempio n. 22
0
        virtual bool run(const string& , BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
            if( replSetBlind )
                return false;

            /* we don't call ReplSetCommand::check() here because heartbeat
               checks many things that are pre-initialization. */
            if( !replSet ) {
                errmsg = "not running with --replSet";
                return false;
            }

            /* we want to keep heartbeat connections open when relinquishing primary.  tag them here. */
            {
                AbstractMessagingPort *mp = cc().port();
                if( mp )
                    mp->tag |= 1;
            }

            if( cmdObj["pv"].Int() != 1 ) {
                errmsg = "incompatible replset protocol version";
                return false;
            }
            {
                string s = string(cmdObj.getStringField("replSetHeartbeat"));
                if( cmdLine.ourSetName() != s ) {
                    errmsg = "repl set names do not match";
                    log() << "cmdline: " << cmdLine._replSet << endl;
                    log() << "s: " << s << endl;
                    result.append("mismatch", true);
                    return false;
                }
            }

            result.append("rs", true);
            if( cmdObj["checkEmpty"].trueValue() ) {
                result.append("hasData", replHasDatabases());
            }
            if( theReplSet == 0 ) {
                string from( cmdObj.getStringField("from") );
                if( !from.empty() && discoveredSeed == 0 ) {
                    discoveredSeed = new string(from);
                }
                errmsg = "still initializing";
                return false;
            }

            if( theReplSet->name() != cmdObj.getStringField("replSetHeartbeat") ) {
                errmsg = "repl set names do not match (2)";
                result.append("mismatch", true);
                return false;
            }
            result.append("set", theReplSet->name());
            result.append("state", theReplSet->state().s);
            result.append("hbmsg", theReplSet->hbmsg());
            result.append("time", (long long) time(0));
            result.appendDate("opTime", theReplSet->lastOpTimeWritten.asDate());
            int v = theReplSet->config().version;
            result.append("v", v);
            if( v > cmdObj["v"].Int() )
                result << "config" << theReplSet->config().asBson();

            return true;
        }
Esempio n. 23
0
        void run() {
            if ( _token.size() == 0  && _name.size() == 0 ) {
                log(1) << "mms not configured" << endl;
                return;
            }

            if ( _token.size() == 0 ) {
                log() << "no token for mms - not running" << endl;
                return;
            }

            if ( _name.size() == 0 ) {
                log() << "no name for mms - not running" << endl;
                return;
            }

            log() << "mms monitor staring...  token:" << _token << " name:" << _name << " interval: " << _secsToSleep << endl;
            Client::initThread( "mms" );
            Client& c = cc();


            // TODO: using direct client is bad, but easy for now

            while ( ! inShutdown() ) {
                sleepsecs( _secsToSleep );

                try {
                    stringstream url;
                    url << _baseurl << "?"
                        << "token=" << _token << "&"
                        << "name=" << _name << "&"
                        << "ts=" << time(0)
                        ;

                    BSONObjBuilder bb;
                    // duplicated so the post has everything
                    bb.append( "token" , _token );
                    bb.append( "name" , _name );
                    bb.appendDate( "ts" , jsTime()  );

                    // any commands
                    _add( bb , "buildinfo" );
                    _add( bb , "serverStatus" );

                    BSONObj postData = bb.obj();

                    log(1) << "mms url: " << url.str() << "\n\t post: " << postData << endl;;

                    HttpClient c;
                    HttpClient::Result r;
                    int rc = c.post( url.str() , postData.jsonString() , &r );
                    log(1) << "\t response code: " << rc << endl;
                    if ( rc != 200 ) {
                        log() << "mms error response code:" << rc << endl;
                        log(1) << "mms error body:" << r.getEntireResponse() << endl;
                    }
                }
                catch ( std::exception& e ) {
                    log() << "mms exception: " << e.what() << endl;
                }
            }

            c.shutdown();
        }
Esempio n. 24
0
void ReplSetImpl::_summarizeStatus(BSONObjBuilder& b) const {
    vector<BSONObj> v;

    const Member *_self = this->_self;
    verify( _self );

    MemberState myState = box.getState();

    // add self
    {
        BSONObjBuilder bb;
        bb.append("_id", (int) _self->id());
        bb.append("name", _self->fullName());
        bb.append("health", 1.0);
        bb.append("state", (int)myState.s);
        bb.append("stateStr", myState.toString());
        bb.append("uptime", (unsigned)(time(0) - cmdLine.started));
        if (!_self->config().arbiterOnly) {
            GTID lastLive;
            GTID lastUnapplied;
            GTID minLive;
            GTID minUnapplied;
            gtidManager->getGTIDs(
                &lastLive,
                &lastUnapplied,
                &minLive,
                &minUnapplied
            );
            bb.appendDate("optimeDate", gtidManager->getCurrTimestamp());
            bb.append("lastGTID", lastLive.toString());
            bb.append("lastUnappliedGTID", lastUnapplied.toString());
            bb.append("minLiveGTID", minLive.toString());
            bb.append("minUnappliedGTID", minUnapplied.toString());
            bb.append("oplogVersion", ReplSetConfig::OPLOG_VERSION);
        }

        int maintenance = _maintenanceMode;
        if (maintenance) {
            bb.append("maintenanceMode", maintenance);
        }

        if (theReplSet) {
            string s = theReplSet->hbmsg();
            if( !s.empty() )
                bb.append("errmsg", s);
        }
        bb.append("self", true);
        v.push_back(bb.obj());
    }

    Member *m =_members.head();
    while( m ) {
        BSONObjBuilder bb;
        bb.append("_id", (int) m->id());
        bb.append("name", m->fullName());
        double h = m->hbinfo().health;
        bb.append("health", h);
        bb.append("state", (int) m->state().s);
        if( h == 0 ) {
            // if we can't connect the state info is from the past and could be confusing to show
            bb.append("stateStr", "(not reachable/healthy)");
        }
        else {
            bb.append("stateStr", m->state().toString());
        }
        bb.append("uptime", (unsigned) (m->hbinfo().upSince ? (time(0)-m->hbinfo().upSince) : 0));
        if (!m->config().arbiterOnly) {
            bb.appendDate("optimeDate", m->hbinfo().opTime);
            bb.append("lastGTID", m->hbinfo().gtid.toString());
            bb.append("lastUnappliedGTID", m->hbinfo().lastUnappliedGTID.toString());
            bb.append("minLiveGTID", m->hbinfo().minLiveGTID.toString());
            bb.append("minUnappliedGTID", m->hbinfo().minUnappliedGTID.toString());
            bb.append("oplogVersion", m->hbinfo().oplogVersion);
        }
        bb.appendTimeT("lastHeartbeat", m->hbinfo().lastHeartbeat);
        bb.appendTimeT("lastHeartbeatRecv", m->getLastRecvHeartbeat());
        bb.append("pingMs", m->hbinfo().ping);
        string s = m->lhb();
        if( !s.empty() )
            bb.append("lastHeartbeatMessage", s);

        if (m->hbinfo().authIssue) {
            bb.append("authenticated", false);
        }

        string syncingTo = m->hbinfo().syncingTo;
        if (!syncingTo.empty()) {
            bb.append("syncingTo", syncingTo);
        }

        v.push_back(bb.obj());
        m = m->next();
    }
    sort(v.begin(), v.end());
    b.append("set", name());
    b.appendTimeT("date", time(0));
    b.append("myState", myState.s);
    const Member *syncTarget = BackgroundSync::get()->getSyncTarget();
    if ( syncTarget &&
            (myState != MemberState::RS_PRIMARY) &&
            (myState != MemberState::RS_SHUNNED) ) {
        b.append("syncingTo", syncTarget->fullName());
    }
    b.append("members", v);
    if( replSetBlind )
        b.append("blind",true); // to avoid confusion if set...normally never set except for testing.
}
Esempio n. 25
0
    void ReplSetImpl::_summarizeStatus(BSONObjBuilder& b) const {
        vector<BSONObj> v;

        const Member *_self = this->_self;
        verify( _self );

        MemberState myState = box.getState();
        const HostAndPort syncTarget = BackgroundSync::get()->getSyncTarget();

        // add self
        {
            BSONObjBuilder bb;
            bb.append("_id", (int) _self->id());
            bb.append("name", _self->fullName());
            bb.append("health", 1.0);
            bb.append("state", (int)myState.s);
            bb.append("stateStr", myState.toString());
            bb.append("uptime", (unsigned)(time(0) - serverGlobalParams.started));
            if (!_self->config().arbiterOnly) {
                bb.appendTimestamp("optime", lastOpTimeWritten.asDate());
                bb.appendDate("optimeDate", lastOpTimeWritten.getSecs() * 1000LL);
            }

            int maintenance = _maintenanceMode;
            if (maintenance) {
                bb.append("maintenanceMode", maintenance);
            }

            if ( !syncTarget.empty() &&
                (myState != MemberState::RS_PRIMARY) &&
                (myState != MemberState::RS_REMOVED) ) {
                bb.append("syncingTo", syncTarget.toString());
            }

            if (theReplSet) {
                string s = theReplSet->hbmsg();
                if( !s.empty() )
                    bb.append("infoMessage", s);

                if (myState == MemberState::RS_PRIMARY) {
                    bb.appendTimestamp("electionTime", theReplSet->getElectionTime().asDate());
                    bb.appendDate("electionDate", theReplSet->getElectionTime().getSecs() * 1000LL);
                }
            }
            bb.append("self", true);
            v.push_back(bb.obj());
        }

        Member *m =_members.head();
        while( m ) {
            BSONObjBuilder bb;
            bb.append("_id", (int) m->id());
            bb.append("name", m->fullName());
            double h = m->hbinfo().health;
            bb.append("health", h);
            bb.append("state", (int) m->state().s);
            if( h == 0 ) {
                // if we can't connect the state info is from the past and could be confusing to show
                bb.append("stateStr", "(not reachable/healthy)");
            }
            else {
                bb.append("stateStr", m->state().toString());
            }
            bb.append("uptime", (unsigned) (m->hbinfo().upSince ? (time(0)-m->hbinfo().upSince) : 0));
            if (!m->config().arbiterOnly) {
                bb.appendTimestamp("optime", m->hbinfo().opTime.asDate());
                bb.appendDate("optimeDate", m->hbinfo().opTime.getSecs() * 1000LL);
            }
            bb.appendTimeT("lastHeartbeat", m->hbinfo().lastHeartbeat);
            bb.appendTimeT("lastHeartbeatRecv", m->hbinfo().lastHeartbeatRecv);
            bb.append("pingMs", m->hbinfo().ping);
            string s = m->lhb();
            if( !s.empty() )
                bb.append("lastHeartbeatMessage", s);

            if (m->hbinfo().authIssue) {
                bb.append("authenticated", false);
            }

            string syncingTo = m->hbinfo().syncingTo;
            if (!syncingTo.empty()) {
                bb.append("syncingTo", syncingTo);
            }

            if (m->state() == MemberState::RS_PRIMARY) {
                bb.appendTimestamp("electionTime", m->hbinfo().electionTime.asDate());
                bb.appendDate("electionDate", m->hbinfo().electionTime.getSecs() * 1000LL);
            }

            v.push_back(bb.obj());
            m = m->next();
        }
        sort(v.begin(), v.end());
        b.append("set", name());
        b.appendTimeT("date", time(0));
        b.append("myState", myState.s);
        if ( !syncTarget.empty() &&
            (myState != MemberState::RS_PRIMARY) &&
            (myState != MemberState::RS_REMOVED) ) {
            b.append("syncingTo", syncTarget.toString());
        }
        b.append("members", v);
    }
Esempio n. 26
0
    /* slave: pull some data from the master's oplog
       note: not yet in db mutex at this point.
       @return -1 error
               0 ok, don't sleep
               1 ok, sleep
    */
    int ReplSource::sync_pullOpLog(int& nApplied) {
        int okResultCode = 1;
        string ns = string("local.oplog.$") + sourceName();
        log(2) << "repl: sync_pullOpLog " << ns << " syncedTo:" << syncedTo.toStringLong() << '\n';

        bool tailing = true;
        oplogReader.tailCheck();

        bool initial = syncedTo.isNull();

        if ( !oplogReader.haveCursor() || initial ) {
            if ( initial ) {
                // Important to grab last oplog timestamp before listing databases.
                syncToTailOfRemoteLog();
                BSONObj info;
                bool ok = oplogReader.conn()->runCommand( "admin", BSON( "listDatabases" << 1 ), info );
                massert( 10389 ,  "Unable to get database list", ok );
                BSONObjIterator i( info.getField( "databases" ).embeddedObject() );
                while( i.moreWithEOO() ) {
                    BSONElement e = i.next();
                    if ( e.eoo() )
                        break;
                    string name = e.embeddedObject().getField( "name" ).valuestr();
                    if ( !e.embeddedObject().getBoolField( "empty" ) ) {
                        if ( name != "local" ) {
                            if ( only.empty() || only == name ) {
                                log( 2 ) << "adding to 'addDbNextPass': "******"$gte", syncedTo.asDate());
            BSONObjBuilder query;
            query.append("ts", q.done());
            if ( !only.empty() ) {
                // note we may here skip a LOT of data table scanning, a lot of work for the master.
                query.appendRegex("ns", string("^") + only); // maybe append "\\." here?
            }
            BSONObj queryObj = query.done();
            // e.g. queryObj = { ts: { $gte: syncedTo } }

            oplogReader.tailingQuery(ns.c_str(), queryObj);
            tailing = false;
        }
        else {
            log(2) << "repl: tailing=true\n";
        }

        if( !oplogReader.haveCursor() ) {
            problem() << "repl: dbclient::query returns null (conn closed?)" << endl;
            oplogReader.resetConnection();
            return -1;
        }

        // show any deferred database creates from a previous pass
        {
            set<string>::iterator i = addDbNextPass.begin();
            if ( i != addDbNextPass.end() ) {
                BSONObjBuilder b;
                b.append("ns", *i + '.');
                b.append("op", "db");
                BSONObj op = b.done();
                sync_pullOpLog_applyOperation(op, false);
            }
        }

        if ( !oplogReader.more() ) {
            if ( tailing ) {
                log(2) << "repl: tailing & no new activity\n";
                if( oplogReader.awaitCapable() )
                    okResultCode = 0; // don't sleep

            }
            else {
                log() << "repl:   " << ns << " oplog is empty\n";
            }
            {
                dblock lk;
                save();
            }
            return okResultCode;
        }

        OpTime nextOpTime;
        {
            BSONObj op = oplogReader.next();
            BSONElement ts = op.getField("ts");
            if ( ts.type() != Date && ts.type() != Timestamp ) {
                string err = op.getStringField("$err");
                if ( !err.empty() ) {
                    // 13051 is "tailable cursor requested on non capped collection"
                    if (op.getIntField("code") == 13051) {
                        problem() << "trying to slave off of a non-master" << '\n';
                        massert( 13344 ,  "trying to slave off of a non-master", false );
                    }
                    else {
                        problem() << "repl: $err reading remote oplog: " + err << '\n';
                        massert( 10390 ,  "got $err reading remote oplog", false );
                    }
                }
                else {
                    problem() << "repl: bad object read from remote oplog: " << op.toString() << '\n';
                    massert( 10391 , "repl: bad object read from remote oplog", false);
                }
            }

            nextOpTime = OpTime( ts.date() );
            log(2) << "repl: first op time received: " << nextOpTime.toString() << '\n';
            if ( initial ) {
                log(1) << "repl:   initial run\n";
            }
            if( tailing ) {
                if( !( syncedTo < nextOpTime ) ) {
                    log() << "repl ASSERTION failed : syncedTo < nextOpTime" << endl;
                    log() << "repl syncTo:     " << syncedTo.toStringLong() << endl;
                    log() << "repl nextOpTime: " << nextOpTime.toStringLong() << endl;
                    assert(false);
                }
                oplogReader.putBack( op ); // op will be processed in the loop below
                nextOpTime = OpTime(); // will reread the op below
            }
            else if ( nextOpTime != syncedTo ) { // didn't get what we queried for - error
                Nullstream& l = log();
                l << "repl:   nextOpTime " << nextOpTime.toStringLong() << ' ';
                if ( nextOpTime < syncedTo )
                    l << "<??";
                else
                    l << ">";

                l << " syncedTo " << syncedTo.toStringLong() << '\n';
                log() << "repl:   time diff: " << (nextOpTime.getSecs() - syncedTo.getSecs()) << "sec\n";
                log() << "repl:   tailing: " << tailing << '\n';
                log() << "repl:   data too stale, halting replication" << endl;
                replInfo = replAllDead = "data too stale halted replication";
                assert( syncedTo < nextOpTime );
                throw SyncException();
            }
            else {
                /* t == syncedTo, so the first op was applied previously or it is the first op of initial query and need not be applied. */
            }
        }

        // apply operations
        {
            int n = 0;
            time_t saveLast = time(0);
            while ( 1 ) {

                bool moreInitialSyncsPending = !addDbNextPass.empty() && n; // we need "&& n" to assure we actually process at least one op to get a sync point recorded in the first place.

                if ( moreInitialSyncsPending || !oplogReader.more() ) {
                    dblock lk;

                    // NOTE aaron 2011-03-29 This block may be unnecessary, but I'm leaving it in place to avoid changing timing behavior.
                    {
                        dbtemprelease t;
                        if ( !moreInitialSyncsPending && oplogReader.more() ) {
                            continue;
                        }
                        // otherwise, break out of loop so we can set to completed or clone more dbs
                    }
                    
                    if( oplogReader.awaitCapable() && tailing )
                        okResultCode = 0; // don't sleep
                    syncedTo = nextOpTime;
                    save(); // note how far we are synced up to now
                    log() << "repl:   applied " << n << " operations" << endl;
                    nApplied = n;
                    log() << "repl:  end sync_pullOpLog syncedTo: " << syncedTo.toStringLong() << endl;
                    break;
                }
                else {
                }

                OCCASIONALLY if( n > 0 && ( n > 100000 || time(0) - saveLast > 60 ) ) {
                    // periodically note our progress, in case we are doing a lot of work and crash
                    dblock lk;
                    syncedTo = nextOpTime;
                    // can't update local log ts since there are pending operations from our peer
                    save();
                    log() << "repl:   checkpoint applied " << n << " operations" << endl;
                    log() << "repl:   syncedTo: " << syncedTo.toStringLong() << endl;
                    saveLast = time(0);
                    n = 0;
                }

                BSONObj op = oplogReader.next();

                unsigned b = replApplyBatchSize;
                bool justOne = b == 1;
                scoped_ptr<writelock> lk( justOne ? 0 : new writelock() );
                while( 1 ) {

                    BSONElement ts = op.getField("ts");
                    if( !( ts.type() == Date || ts.type() == Timestamp ) ) {
                        log() << "sync error: problem querying remote oplog record" << endl;
                        log() << "op: " << op.toString() << endl;
                        log() << "halting replication" << endl;
                        replInfo = replAllDead = "sync error: no ts found querying remote oplog record";
                        throw SyncException();
                    }
                    OpTime last = nextOpTime;
                    nextOpTime = OpTime( ts.date() );
                    if ( !( last < nextOpTime ) ) {
                        log() << "sync error: last applied optime at slave >= nextOpTime from master" << endl;
                        log() << " last:       " << last.toStringLong() << endl;
                        log() << " nextOpTime: " << nextOpTime.toStringLong() << endl;
                        log() << " halting replication" << endl;
                        replInfo = replAllDead = "sync error last >= nextOpTime";
                        uassert( 10123 , "replication error last applied optime at slave >= nextOpTime from master", false);
                    }
                    if ( replSettings.slavedelay && ( unsigned( time( 0 ) ) < nextOpTime.getSecs() + replSettings.slavedelay ) ) {
                        assert( justOne );
                        oplogReader.putBack( op );
                        _sleepAdviceTime = nextOpTime.getSecs() + replSettings.slavedelay + 1;
                        dblock lk;
                        if ( n > 0 ) {
                            syncedTo = last;
                            save();
                        }
                        log() << "repl:   applied " << n << " operations" << endl;
                        log() << "repl:   syncedTo: " << syncedTo.toStringLong() << endl;
                        log() << "waiting until: " << _sleepAdviceTime << " to continue" << endl;
                        return okResultCode;
                    }

                    sync_pullOpLog_applyOperation(op, !justOne);
                    n++;

                    if( --b == 0 )
                        break;
                    // if to here, we are doing mulpile applications in a singel write lock acquisition
                    if( !oplogReader.moreInCurrentBatch() ) {
                        // break if no more in batch so we release lock while reading from the master
                        break;
                    }
                    op = oplogReader.next();

                    getDur().commitIfNeeded();
                }
            }
        }

        return okResultCode;
    }
Esempio n. 27
0
        virtual bool run(const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
            if( replSetBlind ) {
                if (theReplSet) {
                    errmsg = str::stream() << theReplSet->selfFullName() << " is blind";
                }
                return false;
            }

            /* we don't call ReplSetCommand::check() here because heartbeat
               checks many things that are pre-initialization. */
            if( !replSet ) {
                errmsg = "not running with --replSet";
                return false;
            }

            if (!checkAuth(errmsg, result)) {
                return false;
            }

            /* we want to keep heartbeat connections open when relinquishing primary.  tag them here. */
            {
                AbstractMessagingPort *mp = cc().port();
                if( mp )
                    mp->tag |= 1;
            }

            if( cmdObj["pv"].Int() != 1 ) {
                errmsg = "incompatible replset protocol version";
                return false;
            }
            {
                string s = string(cmdObj.getStringField("replSetHeartbeat"));
                if( cmdLine.ourSetName() != s ) {
                    errmsg = "repl set names do not match";
                    log() << "replSet set names do not match, our cmdline: " << cmdLine._replSet << rsLog;
                    log() << "replSet s: " << s << rsLog;
                    result.append("mismatch", true);
                    return false;
                }
            }

            result.append("rs", true);
            if( cmdObj["checkEmpty"].trueValue() ) {
                result.append("hasData", replHasDatabases());
            }
            if( (theReplSet == 0) || (theReplSet->startupStatus == ReplSetImpl::LOADINGCONFIG) ) {
                string from( cmdObj.getStringField("from") );
                if( !from.empty() ) {
                    scoped_lock lck( replSettings.discoveredSeeds_mx );
                    replSettings.discoveredSeeds.insert(from);
                }
                result.append("hbmsg", "still initializing");
                return true;
            }

            if( theReplSet->name() != cmdObj.getStringField("replSetHeartbeat") ) {
                errmsg = "repl set names do not match (2)";
                result.append("mismatch", true);
                return false;
            }
            result.append("set", theReplSet->name());
            result.append("state", theReplSet->state().s);
            result.append("e", theReplSet->iAmElectable());
            result.append("hbmsg", theReplSet->hbmsg());
            result.append("time", (long long) time(0));
            result.appendDate("opTime", theReplSet->lastOpTimeWritten.asDate());
            int v = theReplSet->config().version;
            result.append("v", v);
            if( v > cmdObj["v"].Int() )
                result << "config" << theReplSet->config().asBson();

            return true;
        }
Esempio n. 28
0
        void doTTLForDB( const string& dbName ) {

            //check isMaster before becoming god
            bool isMaster = isMasterNs( dbName.c_str() );

            Client::GodScope god;

            vector<BSONObj> indexes;
            {
                auto_ptr<DBClientCursor> cursor =
                                db.query( dbName + ".system.indexes" ,
                                          BSON( secondsExpireField << BSON( "$exists" << true ) ) ,
                                          0 , /* default nToReturn */
                                          0 , /* default nToSkip */
                                          0 , /* default fieldsToReturn */
                                          QueryOption_SlaveOk ); /* perform on secondaries too */
                if ( cursor.get() ) {
                    while ( cursor->more() ) {
                        indexes.push_back( cursor->next().getOwned() );
                    }
                }
            }
            
            for ( unsigned i=0; i<indexes.size(); i++ ) {
                BSONObj idx = indexes[i];
                

                BSONObj key = idx["key"].Obj();
                if ( key.nFields() != 1 ) {
                    error() << "key for ttl index can only have 1 field" << endl;
                    continue;
                }

                BSONObj query;
                {
                    BSONObjBuilder b;
                    b.appendDate( "$lt" , curTimeMillis64() - ( 1000 * idx[secondsExpireField].numberLong() ) );
                    query = BSON( key.firstElement().fieldName() << b.obj() );
                }
                
                LOG(1) << "TTL: " << key << " \t " << query << endl;
                
                long long n = 0;
                {
                    string ns = idx["ns"].String();
                    Client::WriteContext ctx( ns );
                    NamespaceDetails* nsd = nsdetails( ns );
                    if ( ! nsd ) {
                        // collection was dropped
                        continue;
                    }
                    if ( nsd->setUserFlag( NamespaceDetails::Flag_UsePowerOf2Sizes ) ) {
                        nsd->syncUserFlags( ns );
                    }
                    // only do deletes if on master
                    if ( ! isMaster ) {
                        continue;
                    }

                    n = deleteObjects( ns.c_str() , query , false , true );
                    ttlDeletedDocuments.increment( n );
                }

                LOG(1) << "\tTTL deleted: " << n << endl;
            }
            
            
        }
Esempio n. 29
0
    /* initial oplog application, during initial sync, after cloning. 
       @return false on failure.  
       this method returns an error and doesn't throw exceptions (i think).
    */
    bool ReplSetImpl::initialSyncOplogApplication(
        const Member *source,
        OpTime applyGTE,
        OpTime minValid)
    { 
        if( source == 0 ) return false;

        const string hn = source->h().toString();
        OpTime ts;
        try {
            OplogReader r;
            if( !r.connect(hn) ) { 
                log() << "replSet initial sync error can't connect to " << hn << " to read " << rsoplog << rsLog;
                return false;
            }

            {
                BSONObjBuilder q;
                q.appendDate("$gte", applyGTE.asDate());
                BSONObjBuilder query;
                query.append("ts", q.done());
                BSONObj queryObj = query.done();
                r.query(rsoplog, queryObj);
            }
            assert( r.haveCursor() );

            /* we lock outside the loop to avoid the overhead of locking on every operation.  server isn't usable yet anyway! */
            writelock lk("");

            {
                if( !r.more() ) { 
                    sethbmsg("replSet initial sync error reading remote oplog");
                    log() << "replSet initial sync error remote oplog (" << rsoplog << ") on host " << hn << " is empty?" << rsLog;
                    return false;
                }
                bo op = r.next();
                OpTime t = op["ts"]._opTime();
                r.putBack(op);

                if( op.firstElement().fieldName() == string("$err") ) { 
                    log() << "replSet initial sync error querying " << rsoplog << " on " << hn << " : " << op.toString() << rsLog;
                    return false;
                }

                uassert( 13508 , str::stream() << "no 'ts' in first op in oplog: " << op , !t.isNull() );
                if( t > applyGTE ) {
                    sethbmsg(str::stream() << "error " << hn << " oplog wrapped during initial sync");
                    log() << "replSet initial sync expected first optime of " << applyGTE << rsLog;
                    log() << "replSet initial sync but received a first optime of " << t << " from " << hn << rsLog;
                    return false;
                }
            }

            // todo : use exhaust
            unsigned long long n = 0;
            while( 1 ) { 

                if( !r.more() )
                    break;
                BSONObj o = r.nextSafe(); /* note we might get "not master" at some point */
                {
                    ts = o["ts"]._opTime();

                    /* if we have become primary, we dont' want to apply things from elsewhere
                        anymore. assumePrimary is in the db lock so we are safe as long as 
                        we check after we locked above. */
                    if( (source->state() != MemberState::RS_PRIMARY &&
                         source->state() != MemberState::RS_SECONDARY) ||
                        replSetForceInitialSyncFailure ) {
                        
                        int f = replSetForceInitialSyncFailure;
                        if( f > 0 ) {
                            replSetForceInitialSyncFailure = f-1;
                            log() << "replSet test code invoked, replSetForceInitialSyncFailure" << rsLog;
                            throw DBException("forced error",0);
                        }
                        log() << "replSet we are now primary" << rsLog;
                        throw DBException("primary changed",0);
                    }

                    if( ts >= applyGTE ) {
                        // optimes before we started copying need not be applied.
                        syncApply(o);
                    }
                    _logOpObjRS(o);   /* with repl sets we write the ops to our oplog too */
                }
                if( ++n % 100000 == 0 ) { 
                    // simple progress metering
                    log() << "replSet initialSyncOplogApplication " << n << rsLog;
                }
            }
        }
        catch(DBException& e) { 
            if( ts <= minValid ) {
                // didn't make it far enough
                log() << "replSet initial sync failing, error applying oplog " << e.toString() << rsLog;
                return false;
            }
        }
        return true;
    }
Esempio n. 30
0
    virtual bool run(const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
        if( replSetBlind ) {
            if (theReplSet) {
                errmsg = str::stream() << theReplSet->selfFullName() << " is blind";
            }
            return false;
        }

        MONGO_FAIL_POINT_BLOCK(rsDelayHeartbeatResponse, delay) {
            const BSONObj& data = delay.getData();
            sleepsecs(data["delay"].numberInt());
        }

        /* we don't call ReplSetCommand::check() here because heartbeat
           checks many things that are pre-initialization. */
        if( !replSet ) {
            errmsg = "not running with --replSet";
            return false;
        }

        /* we want to keep heartbeat connections open when relinquishing primary.  tag them here. */
        {
            AbstractMessagingPort *mp = cc().port();
            if( mp )
                mp->tag |= ScopedConn::keepOpen;
        }

        if( cmdObj["pv"].Int() != 1 ) {
            errmsg = "incompatible replset protocol version";
            return false;
        }
        {
            string s = string(cmdObj.getStringField("replSetHeartbeat"));
            if (replSettings.ourSetName() != s) {
                errmsg = "repl set names do not match";
                log() << "replSet set names do not match, our cmdline: " << replSettings.replSet
                      << rsLog;
                log() << "replSet s: " << s << rsLog;
                result.append("mismatch", true);
                return false;
            }
        }

        result.append("rs", true);
        if( cmdObj["checkEmpty"].trueValue() ) {
            result.append("hasData", replHasDatabases());
        }
        if( (theReplSet == 0) || (theReplSet->startupStatus == ReplSetImpl::LOADINGCONFIG) ) {
            string from( cmdObj.getStringField("from") );
            if( !from.empty() ) {
                scoped_lock lck( replSettings.discoveredSeeds_mx );
                replSettings.discoveredSeeds.insert(from);
            }
            result.append("hbmsg", "still initializing");
            return true;
        }

        if( theReplSet->name() != cmdObj.getStringField("replSetHeartbeat") ) {
            errmsg = "repl set names do not match (2)";
            result.append("mismatch", true);
            return false;
        }
        result.append("set", theReplSet->name());

        MemberState currentState = theReplSet->state();
        result.append("state", currentState.s);
        if (currentState == MemberState::RS_PRIMARY) {
            result.appendDate("electionTime", theReplSet->getElectionTime().asDate());
        }

        result.append("e", theReplSet->iAmElectable());
        result.append("hbmsg", theReplSet->hbmsg());
        result.append("time", (long long) time(0));
        result.appendDate("opTime", theReplSet->lastOpTimeWritten.asDate());
        const Member *syncTarget = replset::BackgroundSync::get()->getSyncTarget();
        if (syncTarget) {
            result.append("syncingTo", syncTarget->fullName());
        }

        int v = theReplSet->config().version;
        result.append("v", v);
        if( v > cmdObj["v"].Int() )
            result << "config" << theReplSet->config().asBson();

        Member* from = NULL;
        if (cmdObj.hasField("fromId")) {
            if (v == cmdObj["v"].Int()) {
                from = theReplSet->getMutableMember(cmdObj["fromId"].Int());
            }
        }
        if (!from) {
            from = theReplSet->findByName(cmdObj.getStringField("from"));
            if (!from) {
                return true;
            }
        }

        // if we thought that this node is down, let it know
        if (!from->hbinfo().up()) {
            result.append("stateDisagreement", true);
        }

        // note that we got a heartbeat from this node
        theReplSet->mgr->send(boost::bind(&ReplSet::msgUpdateHBRecv,
                                          theReplSet, from->hbinfo().id(), time(0)));


        return true;
    }