mongodb源码分析(二十五)mongos writeback

        这里的writeback也许可以翻译成回写,是指发生如下情况,来自mongos对mongod的数据请求,但是请求时发现版本不对了(发生了chunk的迁移)那么这里的请求将得不到响应,这里的请求需要以某种方式回到mongos,然后再次发往正确的mongod,这就是所谓的writeback.下面直接来看代码.先来看一份简化了的插入操作代码.

void receivedInsert(Message& m, CurOp& op) {
    if ( handlePossibleShardedMessage( m , 0 ) )//这里判断插入的消息数据是否因为chunk的迁移而不应该在该服务上执行了
        return;
    checkAndInsert(ns, first);
}
inline bool handlePossibleShardedMessage( Message &m, DbResponse * dbresponse ) {
    if( !shardingState.enabled() ) //只有在开启了shard时才有意义
        return false;
    return _handlePossibleShardedMessage(m, dbresponse);
}
    bool _handlePossibleShardedMessage( Message &m, DbResponse* dbresponse ) {
        int op = m.operation();
        if ( op < 2000 || op >= 3000|| op == dbGetMore )
            return false;
        DbMessage d(m);
        const char *ns = d.getns();
        string errmsg;
        // We don't care about the version here, since we're returning it later in the writeback
        ConfigVersion received, wanted;//判断ns对应版本是否变化了,没有变化返回true,则正常执行操作
        if ( shardVersionOk( ns , errmsg, received, wanted ) ) {
            return false;
        }
        //下面已经是因为版本改变之类的信息,使得操作不能继续了
        bool getsAResponse = doesOpGetAResponse( op );//查询操作
        if( getsAResponse ){//这里查询操作,但是chunk版本已改变,所以返回错误消息
            BufBuilder b( 32768 );
            b.skip( sizeof( QueryResult ) );
            {
                BSONObjBuilder bob;
                bob.append( "$err", errmsg );
                bob.append( "ns", ns );
                wanted.addToBSON( bob, "vWanted" );
                received.addToBSON( bob, "vReceived" );
                BSONObj obj = bob.obj();
                b.appendBuf( obj.objdata() , obj.objsize() );
            }
            QueryResult *qr = (QueryResult*)b.buf();
            qr->_resultFlags() = ResultFlag_ErrSet | ResultFlag_ShardConfigStale;
            qr->len = b.len();
            qr->setOperation( opReply );
            qr->cursorId = 0;
            qr->startingFrom = 0;
            qr->nReturned = 1;
            b.decouple();
            Message * resp = new Message();
            resp->setData( qr , true );
            dbresponse->response = resp;
            dbresponse->responseTo = m.header()->id;
            return true;
        }
        OID writebackID;//下面是修改操作,先将这些操作保存起来
        writebackID.initSequential();
        const OID& clientID = ShardedConnectionInfo::get(false)->getID();
        BSONObjBuilder b;
        b.appendBool( "writeBack" , true );
        b.append( "ns" , ns );
        b.append( "id" , writebackID );
        b.append( "connectionId" , cc().getConnectionId() );
        b.append( "instanceIdent" , prettyHostName() );
        wanted.addToBSON( b );
        received.addToBSON( b, "yourVersion" );
        b.appendBinData( "msg" , m.header()->len , bdtCustom , (char*)(m.singleData()) );
        // Don't register the writeback until immediately before we queue it -
        // after this line, mongos will wait for an hour if we don't queue correctly
        lastError.getSafe()->writeback( writebackID );
        writeBackManager.queueWriteBack( clientID.str() , b.obj() );//操作保持到本地queue中
        return true;
    }
继续这里的sha
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值