自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MongoDB源碼分析--Command體系架構(gòu)

運(yùn)維 數(shù)據(jù)庫(kù)運(yùn)維 其他數(shù)據(jù)庫(kù) MongoDB
本文是用一篇專(zhuān)門(mén)介紹MongoDB中Command的體系架構(gòu)的文章,并用例子來(lái)介紹mongod是如何將Command引入其中的。

Command在Mongodb中是一類(lèi)特殊操作,它提供了強(qiáng)大的管理及各項(xiàng)操作(比如建庫(kù),索引,刪除集合等)。可以說(shuō)通過(guò)Command可以完成幾乎所有想做的事情。同時(shí)Mongodb開(kāi)發(fā)者在Command上又做了非常清晰體系架構(gòu)和設(shè)計(jì),便于管理和高效執(zhí)行各種類(lèi)型的Command。

今天就專(zhuān)門(mén)用一篇篇幅來(lái)著重介紹一下其Command的體系架構(gòu),并用例子來(lái)介紹mongod是如何將Command引入其中的。

為了對(duì)其中大部分command對(duì)一個(gè)大致的了解,我們可以用下面指令來(lái)顯示一個(gè)command列表:

  1. mongod --dbpath d:\mongodb\db --port 27017 --rest
  2. 在瀏覽器上輸入鏈接地址:http://localhost:28017/_commands

這里mongod就會(huì)為我們顯示command列表,大約有90多個(gè),這是顯示截圖:

 

上面90多個(gè)類(lèi)中,按其使用場(chǎng)景可以為分如下幾類(lèi),分別是:

  1. dbcommand.cpp:一般數(shù)據(jù)庫(kù)指令,如數(shù)據(jù)庫(kù),索引的創(chuàng)建,重建,打開(kāi)/關(guān)閉等
  2. dbcommands_admin.cpp:管理指令,如CleanCmd,JournalLatencyTestCmd,ValidateCmd,F(xiàn)SyncCommand
  3. dbcommands_generic.cpp:常用指令,ListCommandsCmd,LogRotateCmd,PingCommand,CmdSet,CmdGet等
  4. replset_commands.cpp:復(fù)制集指令,CmdReplSetTest,CmdReplSetGetStatus,CmdReplSetReconfig等
  5. security_commands.cpp:安全指令,CmdGetNonce,CmdLogout,CmdAuthenticate

     

     

  1. commands_admin.cpp:shard管理操作,因其位于mongos項(xiàng)目,這里暫不介紹
  2. commands_public.cpp:shard公用操作,因其位于mongos項(xiàng)目,這里暫不介紹

下面是相關(guān)類(lèi)圖:

-----------------------------分割線--------------------------------

-----------------------------分割線--------------------------------

 -----------------------------分割線--------------------------------

-----------------------------分割線--------------------------------

#p#

首先我們看一下在Command的基類(lèi),其用于定義子類(lèi)要實(shí)現(xiàn)的方法及屬性,自身也實(shí)現(xiàn)了一些通用方法,比如htmlHelp(用于以html方法顯示該command的幫助信息),構(gòu)造方法,findCommand(查詢(xún)命令)等,其聲明如下:

  1. //commands.h  
  2. class Command {  
  3. public:  
  4.    //執(zhí)行當(dāng)前Command時(shí)所使用的鎖類(lèi)型  
  5.    enum LockType { READ = -1/*讀*/ , NONE = 0 /*無(wú)鎖*/, WRITE = 1 /*寫(xiě)*/};  
  6.  
  7.    const string name;  
  8.  
  9.    /* 運(yùn)行指定的命令,需要子類(lèi)實(shí)現(xiàn)  
  10.    fromRepl - command is being invoked as part of replication syncing.  In this situation you  
  11.    normally do not want to log the command to the local oplog.  
  12.  
  13.    如執(zhí)行成功返回true,否則為false, errmsg記錄錯(cuò)誤信息  
  14.    */ 
  15.    virtual bool run(const string& db, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) = 0;  
  16.  
  17.    /*  
  18.    note: logTheTop() MUST be false if READ  
  19.    if NONE, can't use Client::Context setup  
  20.    use with caution  
  21.    */ 
  22.    virtual LockType locktype() const = 0;  
  23.  
  24.    /* 是否有管理特權(quán)才可運(yùn)行該命令 has privileges to run this command. */ 
  25.    virtual bool adminOnly() const {  
  26.       return false;  
  27.    }  
  28.    //html格式的幫助信息  
  29.    void htmlHelp(stringstream&) const;  
  30.  
  31.    /* 與adminOnly相似,但更嚴(yán)格: 要么被驗(yàn)證,要么只運(yùn)行在本地接口(local interface)  
  32.    注:當(dāng)本屬性為true時(shí),adminOnly()也必須為true.  
  33.    */ 
  34.    virtual bool localHostOnlyIfNoAuth(const BSONObj& cmdObj) { return false; }  
  35.  
  36.    /* 如果replication pair 的slaves可以運(yùn)行命令的,則返回true  
  37.    (the command directly from a client -- if fromRepl, always allowed).  
  38.    */ 
  39.    virtual bool slaveOk() const = 0;  
  40.  
  41.    /* 通過(guò)在查詢(xún)命令中打開(kāi) 'slaveok'選項(xiàng),客戶(hù)端強(qiáng)制在一個(gè)slave上運(yùn)行一個(gè)命令時(shí),返回true.  
  42.    */ 
  43.    virtual bool slaveOverrideOk() {  
  44.       return false;  
  45.    }  
  46.  
  47.    /* Override and return true to if true,log the operation (logOp()) to the replication log.  
  48.    (not done if fromRepl of course)  
  49.  
  50.    Note if run() returns false, we do NOT log.  
  51.    */ 
  52.    virtual bool logTheOp() { return false; }  
  53.  
  54.    virtual void help( stringstream& help ) const;  
  55.  
  56.    /* Return true if authentication and security applies to the commands.  Some commands  
  57.    (e.g., getnonce, authenticate) can be done by anyone even unauthorized.  
  58.    */ 
  59.    virtual bool requiresAuth() { return true; }  
  60.  
  61.    /** @param webUI:在web上暴露當(dāng)前command,形如 localhost:28017/<name>  
  62.    @param oldName: 舊選項(xiàng),表示當(dāng)前command的舊(已棄用)名稱(chēng)  
  63.    */ 
  64.    Command(const char *_name, bool webUI = falseconst char *oldName = 0);  
  65.  
  66.    virtual ~Command() {}  
  67.  
  68. protected:  
  69.    BSONObj getQuery( const BSONObj& cmdObj ) {  
  70.      if ( cmdObj["query"].type() == Object )  
  71.         return cmdObj["query"].embeddedObject();  
  72.      if ( cmdObj["q"].type() == Object )  
  73.         return cmdObj["q"].embeddedObject();  
  74.      return BSONObj();  
  75.    }  
  76.  
  77.    static void logIfSlow( const Timer& cmdTimer,  const string& msg);  
  78.    //command map,其包含系統(tǒng)實(shí)現(xiàn)的所有command對(duì)象,以便findCommand查詢(xún)時(shí)使用  
  79.    //注意也包含該command的舊名稱(chēng)(構(gòu)造方法中的oldName參數(shù))所對(duì)應(yīng)的對(duì)象,  
  80.    static map<string,Command*> * _commands;  
  81.    //與上面形同,但不含舊名稱(chēng)的command map  
  82.    static map<string,Command*> * _commandsByBestName;  
  83.    //將web類(lèi)型的command放到該map中  
  84.    static map<string,Command*> * _webCommands;  
  85.  
  86. public:  
  87.    static const map<string,Command*>* commandsByBestName() { return _commandsByBestName; }  
  88.    static const map<string,Command*>* webCommands() { return _webCommands; }  
  89.    /** @return 返回是否找到或已執(zhí)行command */ 
  90.    static bool runAgainstRegistered(const char *ns, BSONObj& jsobj, BSONObjBuilder& anObjBuilder);  
  91.    static LockType locktype( const string& name );  
  92.    //根據(jù)命令名稱(chēng)在集合中找到相應(yīng)Command對(duì)象  
  93.    static Command * findCommand( const string& name );  
  94. }; 

Command基類(lèi)中提供了幾個(gè)map<string,Command*>類(lèi)型的集合map,用于將系統(tǒng)實(shí)現(xiàn)的Command進(jìn)行收集,以便后面findCommand進(jìn)行便歷查詢(xún)時(shí)使用。如下:

  1. //commands.cpp  
  2. Command* Command::findCommand( const string& name ) {  
  3.    //從_commands map中找到指定name的Command對(duì)象  
  4.    map<string,Command*>::iterator i = _commands->find( name );  
  5.    if ( i == _commands->end() )//如果已到結(jié)尾,表示未找到  
  6.       return 0;  
  7.    return i->second;//返回Command對(duì)象  
  8. }  

看到上面代碼中的_commands大家可能要問(wèn),該map是如何初始化并將系統(tǒng)實(shí)現(xiàn)的各個(gè)Command注冊(cè)到其中呢?答案就在Command的構(gòu)造方法中,如下:

  1. //command.cpp  
  2. Command::Command(const char *_name, bool web, const char *oldName) : name(_name) {  
  3.    // register ourself.  
  4.    //如為空(系統(tǒng)剛啟動(dòng)時(shí))則實(shí)例化_commands  
  5.    if ( _commands == 0 )  
  6.       _commands = new map<string,Command*>;  
  7.    //如為空(系統(tǒng)剛啟動(dòng)時(shí))則實(shí)例化_commandsByBestName  
  8.    if( _commandsByBestName == 0 )  
  9.       _commandsByBestName = new map<string,Command*>;  
  10.    Command*& c = (*_commands)[name];//獲取指定名稱(chēng)的command對(duì)象  
  11.    if ( c )//如有,表示之前已注冊(cè)了該command  
  12.       log() << "warning: 2 commands with name: " << _name << endl;  
  13.    //將當(dāng)前command(this)賦值到map中相應(yīng)name的command上  
  14.    c = this;  
  15.    //綁定到_commandsByBestName中的相應(yīng)name上  
  16.    (*_commandsByBestName)[name] = this;  
  17.    //如果命令支持web方式  
  18.    if( web ) {  
  19.       //如為空(系統(tǒng)剛啟動(dòng)時(shí))則實(shí)例化_webCommands  
  20.       if( _webCommands == 0 )  
  21.          _webCommands = new map<string,Command*>;  
  22.       //綁定到_webCommands中的相應(yīng)name上  
  23.       (*_webCommands)[name] = this;  
  24.    }  
  25.    //如有舊名稱(chēng),則也綁到_commands的oldName所指向的command  
  26.    if( oldName )  
  27.       (*_commands)[oldName] = this;  
  28. }  

有了這些還不夠,我們還要從90多個(gè)command子類(lèi)中找出一個(gè)來(lái)實(shí)際分析其實(shí)現(xiàn)的方式,這里以最經(jīng)常使用的count(獲取指定條件的記錄數(shù))來(lái)分析其向map中注冊(cè)command的流程,參見(jiàn)下面代碼段:

  1. //dbcommands.cpp  
  2. /* select count(*) */ 
  3. class CmdCount : public Command {  
  4. public:  
  5.    virtual LockType locktype() const { return READ; }  
  6.    //調(diào)用基類(lèi)的構(gòu)造方法  
  7.    CmdCount() : Command("count") { }  
  8.  
  9.    virtual bool logTheOp() {  
  10.       return false;  
  11.    }  
  12.    virtual bool slaveOk() const {  
  13.       // ok on --slave setups, not ok for nonmaster of a repl pair (unless override)  
  14.       return replSettings.slave == SimpleSlave;  
  15.    }  
  16.    virtual bool slaveOverrideOk() {  
  17.       return true;  
  18.    }  
  19.    virtual bool adminOnly() const {  
  20.       return false;  
  21.    }  
  22.    virtual void help( stringstream& help ) const { help << "count objects in collection"; }  
  23.    virtual bool run(const string& dbname, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool) {  
  24.       string ns = dbname + '.' + cmdObj.firstElement().valuestr();  
  25.       string err;  
  26.       long long n = runCount(ns.c_str(), cmdObj, err);//執(zhí)行查詢(xún)  
  27.       long long nn = n;  
  28.       bool ok = true;  
  29.       if ( n == -1 ) {  
  30.          nn = 0;  
  31.          result.appendBool( "missing" , true );  
  32.       }  
  33.       else if ( n < 0 ) {  
  34.          nn = 0;  
  35.          ok = false;  
  36.          if ( !err.empty() )  
  37.             errmsg = err;  
  38.       }  
  39.       result.append("n", (double) nn);  
  40.       return ok;  
  41.    }  
  42. }  cmdCount; 

上面的CmdCount類(lèi)即是在命令行模式下使用count指令時(shí)對(duì)應(yīng)的代碼塊,其自身的構(gòu)造函數(shù)就直接調(diào)用了基類(lèi)(Command)的構(gòu)造方法。但這里只是定義了還不夠,還需要一個(gè)定義類(lèi)實(shí)例代碼(用于啟動(dòng)構(gòu)造函數(shù)),而這個(gè)任務(wù)就交給了該類(lèi)定義的代碼結(jié)尾處的下面代碼來(lái)實(shí)現(xiàn)了:

  1. } cmdCount; 

可以看到,這里使用的是在類(lèi)聲明后定義對(duì)象的方式來(lái)執(zhí)行構(gòu)造方法(這時(shí)并未使用new實(shí)例化方式來(lái)創(chuàng)建對(duì)象指針),進(jìn)而注冊(cè)該command到map。當(dāng)然繼承自Command的子類(lèi)必須要實(shí)現(xiàn)其中的run()方法,因?yàn)橹挥兴蔷唧wcommand要執(zhí)行的具體邏輯(可參見(jiàn)上面CmdCount的具體實(shí)現(xiàn))。

到這里只能說(shuō)mongod在系統(tǒng)啟動(dòng)到實(shí)始化了相應(yīng)的Command集合map信息,但mongod是如何將client發(fā)來(lái)的操作請(qǐng)求進(jìn)行轉(zhuǎn)換并進(jìn)而執(zhí)行相應(yīng)的command指令的呢?我們接下來(lái)繼續(xù)分析。

之前看過(guò)我的這篇文章的朋友可能還有印象,在mongod啟動(dòng)之后,會(huì)循環(huán)偵聽(tīng)指向端口上的用戶(hù)(client)請(qǐng)求,這些請(qǐng)求在mongod中被改裝成了message在各個(gè)功能類(lèi)中傳遞。當(dāng)用戶(hù)發(fā)送一個(gè)count指令操作時(shí),其會(huì)在query.cpp中執(zhí)行下面方法(以count查詢(xún)指令的執(zhí)行流程為例來(lái)進(jìn)行分析):

  1. //query.cpp  
  2. const char *runQuery(Message& m, QueryMessage& q, CurOp& curop, Message &result) {  
  3.    StringBuilder& ss = curop.debug().str;  
  4.    //構(gòu)造ParsedQuery查詢(xún)對(duì)象,該對(duì)象包括查詢(xún)記錄數(shù)字,以及記錄跳轉(zhuǎn)偏移量等信息,  
  5.  
  6.    //這些值會(huì)在訪問(wèn)磁盤(pán)查詢(xún)時(shí)使用,用法參見(jiàn):query.cpp 662行的virtual void _init()方法  
  7.    shared_ptr<ParsedQuery> pq_shared( new ParsedQuery(q) );  
  8.    ParsedQuery& pq( *pq_shared );  
  9.    ......  
  10.    //對(duì)查詢(xún)命令判斷,指令形如abc.$cmd.findOne( { ismaster:1 } )  
  11.    if ( pq.couldBeCommand() ) {//_ns中包括$cmd字符串  
  12.   BufBuilder bb;  
  13.   bb.skip(sizeof(QueryResult));  
  14.   BSONObjBuilder cmdResBuf;  
  15.   //對(duì)查詢(xún)權(quán)限判斷,并執(zhí)行相應(yīng)查詢(xún)指令  
  16.   if ( runCommands(ns, jsobj, curop, bb, cmdResBuf, false, queryOptions) ) {  
  17.      ss << " command: ";  
  18.      jsobj.toString( ss );  
  19.      curop.markCommand();  
  20.      auto_ptr< QueryResult > qr;  
  21.      qr.reset( (QueryResult *) bb.buf() );  
  22.      bb.decouple();  
  23.      qr->setResultFlagsToOk();  
  24.      qr->len = bb.len();  
  25.      ss << " reslen:" << bb.len();  
  26.      qr->setOperation(opReply);  
  27.      qr->cursorId = 0;  
  28.      qr->startingFrom = 0;  
  29.      qr->nReturned = 1;  
  30.      result.setData( qr.release(), true );//設(shè)置返回結(jié)果  
  31.   }  
  32.   else {  
  33.      uasserted(13530, "bad or malformed command request?");  
  34.   }  
  35.   return 0;  
  36.    }  
  37. .....  

上面代碼對(duì)傳遞來(lái)的查詢(xún)消息QueryMessage進(jìn)行分析之后,如果發(fā)現(xiàn)其為command時(shí),執(zhí)行runCommands方法:

  1. //query.cpp     
  2. bool runCommands(const char *ns, BSONObj& jsobj, CurOp& curop, BufBuilder &b, BSONObjBuilder& anObjBuilder, bool fromRepl, int queryOptions) {  
  3.    try {  
  4.       return _runCommands(ns, jsobj, b, anObjBuilder, fromRepl, queryOptions);  
  5.    }  
  6.    catch ( AssertionException& e ) {  
  7.       e.getInfo().append( anObjBuilder , "assertion" , "assertionCode" );  
  8.    }  
  9.    curop.debug().str << " assertion ";  
  10.    anObjBuilder.append("errmsg""db assertion failure");  
  11.    anObjBuilder.append("ok", 0.0);  
  12.    BSONObj x = anObjBuilder.done();  
  13.    b.appendBuf((void*) x.objdata(), x.objsize());  
  14.    return true;  
  15. }  

接著其會(huì)執(zhí)行dbcommands.cpp中的_runCommands()方法

  1. //dbcommands.cpp  
  2.   bool _runCommands(const char *ns, BSONObj& _cmdobj, BufBuilder &b, BSONObjBuilder& anObjBuilder, bool fromRepl, int queryOptions) {  
  3.   cc().curop()->ensureStarted();  
  4.   string dbname = nsToDatabase( ns );  
  5.  
  6.   if( logLevel >= 1 )  
  7.      log() << "run command " << ns << ' ' << _cmdobj << endl;  
  8.  
  9.   const char *p = strchr(ns, '.');  
  10.   if ( !p ) return false;  
  11.   //再次進(jìn)行cmd判斷,以確定是command  
  12.   if ( strcmp(p, ".$cmd") != 0 ) return false;  
  13.  
  14.   BSONObj jsobj;  
  15.   {  
  16.      BSONElement e = _cmdobj.firstElement();  
  17.      if ( e.type() == Object && string("query") == e.fieldName() ) {  
  18.         jsobj = e.embeddedObject();  
  19.      }  
  20.      else {  
  21.         jsobj = _cmdobj;  
  22.      }  
  23.   }  
  24.  
  25.   Client& client = cc();  
  26.   bool ok = false;  
  27.  
  28.   BSONElement e = jsobj.firstElement();  
  29.   //根據(jù)command名稱(chēng)從map中找出相應(yīng)的command對(duì)象  
  30.   Command * c = e.type() ? Command::findCommand( e.fieldName() ) : 0;  
  31.  
  32.   if ( c ) {  
  33.      //執(zhí)行該對(duì)象  
  34.      ok = execCommand( c , client , queryOptions , ns , jsobj , anObjBuilder , fromRepl );  
  35.   }  
  36.   else {  
  37.      anObjBuilder.append("errmsg", str::stream() << "no such cmd: " << e.fieldName() );  
  38.      anObjBuilder.append("bad cmd" , _cmdobj );  
  39.   }  
  40.  
  41.   // switch to bool, but wait a bit longer before switching?  
  42.   // anObjBuilder.append("ok", ok);  
  43.   anObjBuilder.append("ok", ok?1.0:0.0);  
  44.   BSONObj x = anObjBuilder.done();  
  45.   b.appendBuf((void*) x.objdata(), x.objsize());  
  46.  
  47.   return true;  

上面代碼主要是從map中找出相應(yīng)的command對(duì)象,并將該對(duì)象及操作命令參數(shù)和client(用于獲取其中的認(rèn)證信息,以確定其執(zhí)行權(quán)限)作為參數(shù),來(lái)調(diào)用 execCommand方法:

  1. //dbcommands.cpp  
  2. bool execCommand( Command * c ,  
  3.   Client& client , int queryOptions ,  
  4.   const char *cmdns, BSONObj& cmdObj ,  
  5.   BSONObjBuilder& result /*返回command執(zhí)行結(jié)果*/,  
  6.   bool fromRepl ) {  
  7.  
  8.      string dbname = nsToDatabase( cmdns );  
  9.  
  10.      AuthenticationInfo *ai = client.getAuthenticationInfo();  
  11.      
  12.      if( c->adminOnly() /*如果需要有管理特權(quán)開(kāi)可運(yùn)行*/ 
  13.      && c->localHostOnlyIfNoAuth( cmdObj ) /*要么被驗(yàn)證,要么只運(yùn)行在本地接口*/ 
  14.      && noauth && !ai->isLocalHost ) {//未認(rèn)證 且 不是在本地運(yùn)行  
  15.         result.append( "errmsg" ,  
  16.         "unauthorized: this command must run from localhost when running db without auth" );  
  17.         log() << "command denied: " << cmdObj.toString() << endl;  
  18.         return false;  
  19.      }  
  20.  
  21.     if ( c->adminOnly() && ! fromRepl && dbname != "admin" ) {  
  22.        result.append( "errmsg" ,  "access denied; use admin db" );  
  23.        log() << "command denied: " << cmdObj.toString() << endl;  
  24.        return false;  
  25.     }  
  26.  
  27.    if ( cmdObj["help"].trueValue() ) {  
  28.       stringstream ss;  
  29.       ss << "help for: " << c->name << " ";  
  30.       c->help( ss );  
  31.       result.append( "help" , ss.str() );  
  32.       result.append( "lockType" , c->locktype() );  
  33.       return true;  
  34.    }  
  35.  
  36.    bool canRunHere =  
  37.    isMaster( dbname.c_str() ) /*如為master庫(kù)*/||  
  38.    c->slaveOk() /*如果replication pair 的slaves可以運(yùn)行命令*/||  
  39.    ( c->slaveOverrideOk() && ( queryOptions & QueryOption_SlaveOk ) ) ||  
  40.    fromRepl;  
  41.  
  42.    if ( ! canRunHere ) {  
  43.       result.append( "errmsg" , "not master" );  
  44.       return false;  
  45.    }  
  46.  
  47.    if ( c->adminOnly() )  
  48.       log( 2 ) << "command: " << cmdObj << endl;  
  49.  
  50.    //如當(dāng)前command無(wú)須鎖時(shí)  
  51.    if ( c->locktype() == Command::NONE ) {  
  52.       // we also trust that this won't crash  
  53.       string errmsg;  
  54.       //運(yùn)行當(dāng)前command  
  55.       int ok = c->run( dbname , cmdObj , errmsg , result , fromRepl );  
  56.       if ( ! ok )  
  57.          result.append( "errmsg" , errmsg );  
  58.       return ok;  
  59.    }  
  60.    //判斷執(zhí)行當(dāng)前command是否需要'寫(xiě)鎖'(每個(gè)command子類(lèi)都有該屬性),枚舉定義如下(command.h):  
  61.    //enum LockType { READ = -1/*讀*/ , NONE = 0 /*無(wú)鎖*/, WRITE = 1 /*寫(xiě)*/};  
  62.    bool needWriteLock = c->locktype() == Command::WRITE;  
  63.  
  64.    if ( ! needWriteLock ) {  
  65.       assert( ! c->logTheOp() );  
  66.    }  
  67.  
  68.    mongolock lk( needWriteLock );//聲明鎖對(duì)象  
  69.    Client::Context ctx( dbname , dbpath , &lk , c->requiresAuth() );  
  70.  
  71.    try {  
  72.       string errmsg;  
  73.       //運(yùn)行當(dāng)前command(本文中提到的count命令)  
  74.       if ( ! c->run(dbname, cmdObj, errmsg, result, fromRepl ) ) {  
  75.          result.append( "errmsg" , errmsg );  
  76.          return false;  
  77.       }  
  78.    }  
  79.    catch ( DBException& e ) {  
  80.       stringstream ss;  
  81.       ss << "exception: " << e.what();  
  82.       result.append( "errmsg" , ss.str() );  
  83.       result.append( "code" , e.getCode() );  
  84.       return false;  
  85.    }  
  86.  
  87.    if ( c->logTheOp() && ! fromRepl ) {  
  88.       logOp("c", cmdns, cmdObj);  
  89.    }  
  90.  
  91.    return true;  

到這里,流程基本就執(zhí)行完畢了,之后它會(huì)將結(jié)果傳給result(其傳參為引用類(lèi)型,即:"& result"方式).

#p#

***用一張時(shí)間序來(lái)大體回顧一下這***程:

好了,今天的內(nèi)容到這里就告一段落了。

參考鏈接:
http://www.mongodb.org/display/DOCS/Commands
http://www.10gen.com/reference

原文鏈接:http://www.cnblogs.com/daizhj/archive/2011/04/29/mongos_command_source_code.html

【編輯推薦】

  1. Mongodb源碼分析--內(nèi)存文件映射(MMAP)
  2. 走進(jìn)MongoDB的世界 展開(kāi)MongoDB的學(xué)習(xí)之旅
  3. 淺析Mongodb源碼之游標(biāo)Cursor
  4. 野心勃勃的NoSQL新貴 MongoDB應(yīng)用實(shí)戰(zhàn)
  5. MongoDB與CouchDB全方位對(duì)比

 

責(zé)任編輯:艾婧 來(lái)源: 博客園
相關(guān)推薦

2011-05-26 10:05:48

MongoDB

2011-05-26 16:18:51

Mongodb

2019-07-01 12:55:05

安全體系架構(gòu)網(wǎng)絡(luò)安全企業(yè)安全

2011-04-25 17:15:39

MongodbMMAP

2016-11-25 13:14:50

Flume架構(gòu)源碼

2016-11-29 09:38:06

Flume架構(gòu)核心組件

2016-11-25 13:26:50

Flume架構(gòu)源碼

2009-12-25 16:24:14

防火墻三大體系架構(gòu)前景分析

2019-10-16 16:33:41

Docker架構(gòu)語(yǔ)言

2022-03-18 15:55:15

鴻蒙操作系統(tǒng)架構(gòu)

2017-07-26 09:41:28

MyCATSQLMongoDB

2011-09-16 14:43:52

MongoDB

2023-06-02 08:16:14

MySQL體系架構(gòu)

2016-09-04 14:00:31

Spark

2016-11-29 16:59:46

Flume架構(gòu)源碼

2021-02-19 06:56:33

架構(gòu)協(xié)程應(yīng)用

2017-06-27 14:05:19

2009-12-23 10:13:20

WPF體系架構(gòu)

2021-01-06 10:09:38

MySQL

2022-06-07 10:33:29

Camera組件鴻蒙
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)