上一篇文章分析到了客户端查询请求的发送,接着分析服务端的处理动作,分析从服务端响应开始到数据库
正确加载止,主要流程为数据库的读入过程与用户的认证.
mongod服务对于客户端请求的处理在mongo/db/db.cpp MyMessageHandler::process中,其中调用了
函数assembleResponse完成请求响应,我们就从这个函数开始入手分析,代码很长,删除一些支流或者不相关的代码.
void assembleResponse( Message &m, DbResponse &dbresponse, const HostAndPort& remote ) {
if ( op == dbQuery ) {
if( strstr(ns, ".$cmd") ) {
isCommand = true;
opwrite(m);//写入诊断用的log,默认loglevel为0,未开启,需要开启启动时加入--diaglog x,0 = off; 1 = writes, 2 = reads, 3 = both
if( strstr(ns, ".$cmd.sys.") ) {//7 = log a few reads, and all writes.
if( strstr(ns, "$cmd.sys.inprog") ) {
inProgCmd(m, dbresponse);//查看当前进度的命令
return;
}
if( strstr(ns, "$cmd.sys.killop") ) {
killOp(m, dbresponse);//终止当前操作
return;
}
if( strstr(ns, "$cmd.sys.unlock") ) {
unlockFsync(ns, m, dbresponse);
return;
}
}
}
else {
opread(m);
}
}
else if( op == dbGetMore ) {
opread(m);
}
else {
opwrite(m);
}
long long logThreshold = cmdLine.slowMS;//启动的时候设置的参数默认是100ms,当操作超过了这个时间且启动时设置--profile为1或者2
bool shouldLog = logLevel >= 1;//时mongodb将记录这次慢操作,1为只记录慢操作,即操作时间大于了设置的slowMS,2表示记录所有操作
if ( op == dbQuery ) { //可通过--slowms设置slowMS
if ( handlePossibleShardedMessage( m , &dbresponse ) )//这里和shard有关,以后会的文章会讲到
return;
receivedQuery(c , dbresponse, m );//真正的查询入口
}
else if ( op == dbGetMore ) {//已经查询了数据,这里只是执行得到更多数据的入口
if ( ! receivedGetMore(dbresponse, m, currentOp) )
shouldLog = true;
}
if ( op == dbKillCursors ) {
currentOp.ensureStarted();
logThreshold = 10;
receivedKillCursors(m);
}
else if ( op == dbInsert ) {//插入操作入口
receivedInsert(m, currentOp);
}
else if ( op == dbUpdate ) {//更新操作入口
receivedUpdate(m, currentOp);
}
else if ( op == dbDelete ) {//删除操作入口
receivedDelete(m, currentOp);
}
if ( currentOp.shouldDBProfile( debug.executionTime ) ) {//该操作将被记录,原因可能有二:一,启动时设置--profile 2,则所有操作将被
// performance profiling is on //记录.二,启动时设置--profile 1,且操作时间超过了默认的slowMs,那么操作将被 else {//这个地方if部分被删除了,就是在不能获取锁的状况下不记录该操作的代码
Lock::DBWrite lk( currentOp.getNS() );//记录具体记录操作,就是在xxx.system.profile集合中插入该操作的具体记录
if ( dbHolder()._isLoaded( nsToDatabase( currentOp.getNS() ) , dbpath ) ) {
Client::Context cx( currentOp.getNS(), dbpath, false )