这里的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