Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
MongodbÔ´Âë·ÖÎö--CommandÌåϵ¼Ü¹¹
 
×÷Õߣº´úÕð¾ü À´Ô´£º²©¿ÍÔ° ·¢²¼ÓÚ£º2015-04-03
  2313  次浏览      31
 

CommandÔÚMongodbÖÐÊÇÒ»ÀàÌØÊâ²Ù×÷£¬ËüÌṩÁËÇ¿´óµÄ¹ÜÀí¼°¸÷Ïî²Ù×÷£¨±ÈÈ罨¿â£¬Ë÷Òý£¬É¾³ý¼¯ºÏµÈ£©¡£¿ÉÒÔ˵ͨ¹ýCommand¿ÉÒÔÍê³É¼¸ºõËùÓÐÏë×öµÄÊÂÇ顣ͬʱMongodb¿ª·¢ÕßÔÚCommandÉÏÓÖ×öÁ˷dz£ÇåÎúÌåϵ¼Ü¹¹ºÍÉè¼Æ£¬±ãÓÚ¹ÜÀíºÍ¸ßЧִÐи÷ÖÖÀàÐ͵ÄCommand¡£

½ñÌì¾ÍרÃÅÓÃһƪƪ·ùÀ´×ÅÖØ½éÉÜÒ»ÏÂÆäCommandµÄÌåϵ¼Ü¹¹£¬²¢ÓÃÀý×ÓÀ´½éÉÜmongodÊÇÈçºÎ½«CommandÒýÈëÆäÖеġ£

ΪÁË¶ÔÆäÖд󲿷Öcommand¶ÔÒ»¸ö´óÖµÄÁ˽⣬ÎÒÃÇ¿ÉÒÔÓÃÏÂÃæÖ¸ÁîÀ´ÏÔʾһ¸öcommandÁÐ±í£º

1.mongod --dbpath d:\mongodb\db --port 27017 --rest
2.ÔÚä¯ÀÀÆ÷ÉÏÊäÈëÁ´½ÓµØÖ·£ºhttp://localhost:28017/_commands

ÕâÀïmongod¾Í»áΪÎÒÃÇÏÔʾcommandÁÐ±í£¬´óÔ¼ÓÐ90¶à¸ö£¬ÕâÊÇÏÔʾ½ØÍ¼£º

ÉÏÃæ90¶à¸öÀàÖУ¬°´ÆäʹÓó¡¾°¿ÉÒÔΪ·ÖÈçϼ¸À࣬·Ö±ðÊÇ£º

dbcommand.cpp£ºÒ»°ãÊý¾Ý¿âÖ¸ÁÈçÊý¾Ý¿â£¬Ë÷ÒýµÄ´´½¨£¬Öؽ¨£¬´ò¿ª/¹Ø±ÕµÈ

dbcommands_admin.cpp£º¹ÜÀíÖ¸ÁÈçCleanCmd£¬JournalLatencyTestCmd£¬ValidateCmd£¬FSyncCommand

dbcommands_generic.cpp£º³£ÓÃÖ¸Áî,ListCommandsCmd,LogRotateCmd,PingCommand,CmdSet,CmdGetµÈ

replset_commands.cpp£º¸´ÖƼ¯Ö¸ÁCmdReplSetTest£¬CmdReplSetGetStatus,CmdReplSetReconfigµÈ

security_commands.cpp£º°²È«Ö¸Áî,CmdGetNonce,CmdLogout,CmdAuthenticate

commands_admin.cpp£ºshard¹ÜÀí²Ù×÷£¬ÒòÆäλÓÚmongosÏîÄ¿£¬ÕâÀïÔݲ»½éÉÜ

commands_public.cpp£ºshard¹«ÓòÙ×÷£¬ÒòÆäλÓÚmongosÏîÄ¿£¬ÕâÀïÔݲ»½éÉÜ

ÏÂÃæÊÇÏà¹ØÀàͼ£º

Ê×ÏÈÎÒÃÇ¿´Ò»ÏÂÔÚCommandµÄ»ùÀ࣬ÆäÓÃÓÚ¶¨Òå×ÓÀàҪʵÏֵķ½·¨¼°ÊôÐÔ£¬×ÔÉíҲʵÏÖÁËһЩͨÓ÷½·¨£¬±ÈÈçhtmlHelp(ÓÃÓÚÒÔhtml·½·¨ÏÔʾ¸ÃcommandµÄ°ïÖúÐÅÏ¢),¹¹Ôì·½·¨£¬findCommand(²éѯÃüÁî)µÈ£¬ÆäÉùÃ÷ÈçÏ£º

//commands.h
    class Command {
    public:
        //Ö´Ðе±Ç°CommandʱËùʹÓõÄËøÀàÐÍ
        enum LockType { READ = -1/*¶Á*/ , NONE = 0 /*ÎÞËø*/, WRITE = 1 /*д*/};

        const string name;

        /* ÔËÐÐÖ¸¶¨µÄÃüÁÐèÒª×ÓÀàʵÏÖ
           fromRepl - command is being invoked as part of replication syncing.  In this situation you
                      normally do not want to log the command to the local oplog.

           ÈçÖ´Ðгɹ¦·µ»Øtrue,·ñÔòΪfalse, errmsg¼Ç¼´íÎóÐÅÏ¢
        */
        virtual bool run(const string& db, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) = 0;

        /*
           note: logTheTop() MUST be false if READ
           if NONE, can't use Client::Context setup
                    use with caution
         */
        virtual LockType locktype() const = 0;

        /* ÊÇ·ñÓйÜÀíÌØÈ¨²Å¿ÉÔËÐиÃÃüÁî has privileges to run this command. */
        virtual bool adminOnly() const {
            return false;
        }
        //html¸ñʽµÄ°ïÖúÐÅÏ¢
        void htmlHelp(stringstream&) const;

        /* ÓëadminOnlyÏàËÆ,µ«¸üÑϸñ: Ҫô±»ÑéÖ¤£¬ÒªÃ´Ö»ÔËÐÐÔÚ±¾µØ½Ó¿Ú£¨local interface£©          
           ×¢£ºµ±±¾ÊôÐÔΪtrueʱ£¬adminOnly()Ò²±ØÐëΪtrue.
        */
        virtual bool localHostOnlyIfNoAuth(const BSONObj& cmdObj) { return false; }

        /* Èç¹ûreplication pair µÄslaves¿ÉÒÔÔËÐÐÃüÁîµÄ£¬Ôò·µ»Øtrue
           (the command directly from a client -- if fromRepl, always allowed).
        */
        virtual bool slaveOk() const = 0;

        /* ͨ¹ýÔÚ²éѯÃüÁîÖдò¿ª 'slaveok'Ñ¡Ï¿Í»§¶ËÇ¿ÖÆÔÚÒ»¸öslaveÉÏÔËÐÐÒ»¸öÃüÁîʱ£¬·µ»Øtrue.
        */
        virtual bool slaveOverrideOk() {
            return false;
        }

        /* Override and return true to if true,log the operation (logOp()) to the replication log.
           (not done if fromRepl of course)

           Note if run() returns false, we do NOT log.
        */
        virtual bool logTheOp() { return false; }

        virtual void help( stringstream& help ) const;

        /* Return true if authentication and security applies to the commands.  Some commands
           (e.g., getnonce, authenticate) can be done by anyone even unauthorized.
        */
        virtual bool requiresAuth() { return true; }

        /** @param webUI£ºÔÚwebÉϱ©Â¶µ±Ç°command£¬ÐÎÈç localhost:28017/
            @param oldName£º ¾ÉÑ¡Ï±íʾµ±Ç°commandµÄ¾É(ÒÑÆúÓÃ)Ãû³Æ
        */
        Command(const char *_name, bool webUI = false, const char *oldName = 0);

        virtual ~Command() {}

    protected:
        BSONObj getQuery( const BSONObj& cmdObj ) {
            if ( cmdObj["query"].type() == Object )
                return cmdObj["query"].embeddedObject();
            if ( cmdObj["q"].type() == Object )
                return cmdObj["q"].embeddedObject();
            return BSONObj();
        }

        static void logIfSlow( const Timer& cmdTimer,  const string& msg);
        //command map,Æä°üº¬ÏµÍ³ÊµÏÖµÄËùÓÐcommand¶ÔÏó£¬ÒÔ±ãfindCommand²éѯʱʹÓÃ
        //×¢ÒâÒ²°üº¬¸ÃcommandµÄ¾ÉÃû³Æ£¨¹¹Ôì·½·¨ÖеÄoldName²ÎÊý£©Ëù¶ÔÓ¦µÄ¶ÔÏó£¬
        static map<string,Command*> * _commands;
        //ÓëÉÏÃæÐÎͬ£¬µ«²»º¬¾ÉÃû³ÆµÄcommand map
        static map<string,Command*> * _commandsByBestName;
        //½«webÀàÐ͵Äcommand·Åµ½¸ÃmapÖÐ
        static map<string,Command*> * _webCommands;

    public:
        static const map<string,Command*>* commandsByBestName() { return _commandsByBestName; }
        static const map<string,Command*>* webCommands() { return _webCommands; }
        /** @return ·µ»ØÊÇ·ñÕÒµ½»òÒÑÖ´ÐÐcommand */
        static bool runAgainstRegistered(const char *ns, BSONObj& jsobj, BSONObjBuilder& anObjBuilder);
        static LockType locktype( const string& name );
        //¸ù¾ÝÃüÁîÃû³ÆÔÚ¼¯ºÏÖÐÕÒµ½ÏàÓ¦Command¶ÔÏó
        static Command * findCommand( const string& name );
    };

Command»ùÀàÖÐÌṩÁ˼¸¸ömap<string,Command*>ÀàÐ͵ļ¯ºÏmap£¬ÓÃÓÚ½«ÏµÍ³ÊµÏÖµÄCommand½øÐÐÊÕ¼¯£¬ÒÔ±ãºóÃæfindCommand½øÐбãÀú²éѯʱʹÓá£ÈçÏ£º

//commands.cpp
Command* Command::findCommand( const string& name ) {
//´Ó_commands mapÖÐÕÒµ½Ö¸¶¨nameµÄCommand¶ÔÏó
map<string,Command*>::iterator i = _commands->find( name );
if ( i == _commands->end() )//Èç¹ûÒѵ½½á⣬±íʾδÕÒµ½
return 0;
return i->second;//·µ»ØCommand¶ÔÏó
}

¿´µ½ÉÏÃæ´úÂëÖеÄ_commands´ó¼Ò¿ÉÄÜÒªÎÊ£¬¸ÃmapÊÇÈçºÎ³õʼ»¯²¢½«ÏµÍ³ÊµÏֵĸ÷¸öCommand×¢²áµ½ÆäÖÐÄØ£¿´ð°¸¾ÍÔÚCommandµÄ¹¹Ôì·½·¨ÖУ¬ÈçÏ£º

//command.cpp
Command::Command(const char *_name, bool web, const char *oldName) : name(_name) {
// register ourself.
//ÈçΪ¿Õ£¨ÏµÍ³¸ÕÆô¶¯Ê±£©ÔòʵÀý»¯_commands
if ( _commands == 0 )
_commands = new map<string,Command*>;
//ÈçΪ¿Õ£¨ÏµÍ³¸ÕÆô¶¯Ê±£©ÔòʵÀý»¯_commandsByBestName
if( _commandsByBestName == 0 )
_commandsByBestName = new map<string,Command*>;
Command*& c = (*_commands)[name];//»ñȡָ¶¨Ãû³ÆµÄcommand¶ÔÏó
if ( c )//ÈçÓУ¬±íʾ֮ǰÒÑ×¢²áÁ˸Ãcommand
log() << "warning: 2 commands with name: " << _name << endl;
//½«µ±Ç°command£¨this£©¸³Öµµ½mapÖÐÏàÓ¦nameµÄcommandÉÏ
c = this;
//°ó¶¨µ½_commandsByBestNameÖеÄÏàÓ¦nameÉÏ
(*_commandsByBestName)[name] = this;
//Èç¹ûÃüÁîÖ§³Öweb·½Ê½
if( web ) {
//ÈçΪ¿Õ£¨ÏµÍ³¸ÕÆô¶¯Ê±£©ÔòʵÀý»¯_webCommands
if( _webCommands == 0 )
_webCommands = new map<string,Command*>;
//°ó¶¨µ½_webCommandsÖеÄÏàÓ¦nameÉÏ
(*_webCommands)[name] = this;
}
//ÈçÓоÉÃû³Æ£¬ÔòÒ²°óµ½_commandsµÄoldNameËùÖ¸ÏòµÄcommand
if( oldName )
(*_commands)[oldName] = this;
}

ÓÐÁËÕâЩ»¹²»¹»£¬ÎÒÃÇ»¹Òª´Ó90¶à¸öcommand×ÓÀàÖÐÕÒ³öÒ»¸öÀ´Êµ¼Ê·ÖÎöÆäʵÏֵķ½Ê½£¬ÕâÀïÒÔ×î¾­³£Ê¹ÓõÄcount(»ñȡָ¶¨Ìõ¼þµÄ¼Ç¼Êý)À´·ÖÎöÆäÏòmapÖÐ×¢²ácommandµÄÁ÷³Ì£¬²Î¼ûÏÂÃæ´úÂë¶Î£º

//dbcommands.cpp
/* select count(*) */
class CmdCount : public Command {
public:
virtual LockType locktype() const { return READ; }
//µ÷ÓûùÀàµÄ¹¹Ôì·½·¨
CmdCount() : Command("count") { } virtual bool logTheOp() {
return false;
}
virtual bool slaveOk() const {
// ok on --slave setups, not ok for nonmaster of a repl pair (unless override)
return replSettings.slave == SimpleSlave;
}
virtual bool slaveOverrideOk() {
return true;
}
virtual bool adminOnly() const {
return false;
}
virtual void help( stringstream& help ) const { help << "count objects in collection"; }
virtual bool run(const string& dbname, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool) {
string ns = dbname + '.' + cmdObj.firstElement().valuestr();
string err;
long long n = runCount(ns.c_str(), cmdObj, err);//Ö´Ðвéѯ
long long nn = n;
bool ok = true;
if ( n == -1 ) {
nn = 0;
result.appendBool( "missing" , true );
}
else if ( n < 0 ) {
nn = 0;
ok = false;
if ( !err.empty() )
errmsg = err;
}
result.append("n", (double) nn);
return ok;
}
} cmdCount;

ÉÏÃæµÄCmdCountÀ༴ÊÇÔÚÃüÁîÐÐģʽÏÂʹÓÃcountÖ¸Áîʱ¶ÔÓ¦µÄ´úÂë¿é£¬Æä×ÔÉíµÄ¹¹Ô캯Êý¾ÍÖ±½Óµ÷ÓÃÁË»ùÀà(Command)µÄ¹¹Ôì·½·¨¡£µ«ÕâÀïÖ»ÊǶ¨ÒåÁË»¹²»¹»£¬»¹ÐèÒªÒ»¸ö¶¨ÒåÀàʵÀý´úÂ루ÓÃÓÚÆô¶¯¹¹Ô캯Êý£©£¬¶øÕâ¸öÈÎÎñ¾Í½»¸øÁ˸ÃÀඨÒåµÄ´úÂë½áβ´¦µÄÏÂÃæ´úÂëÀ´ÊµÏÖÁË£º

} cmdCount;

¿ÉÒÔ¿´µ½£¬ÕâÀïʹÓõÄÊÇÔÚÀàÉùÃ÷ºó¶¨Òå¶ÔÏóµÄ·½Ê½À´Ö´Ðй¹Ôì·½·¨£¨Õâʱ²¢Î´Ê¹ÓÃnewʵÀý»¯·½Ê½À´´´½¨¶ÔÏóÖ¸Õ룩£¬½ø¶ø×¢²á¸Ãcommandµ½map¡£µ±È»¼Ì³Ð×ÔCommandµÄ×ÓÀà±ØÐëҪʵÏÖÆäÖеÄrun()·½·¨,ÒòΪֻÓÐËüÊǾßÌåcommandÒªÖ´ÐеľßÌåÂß¼­£¨¿É²Î¼ûÉÏÃæCmdCountµÄ¾ßÌåʵÏÖ£©¡£

µ½ÕâÀïÖ»ÄÜ˵mongodÔÚϵͳÆô¶¯µ½ÊµÊ¼»¯ÁËÏàÓ¦µÄCommand¼¯ºÏmapÐÅÏ¢£¬µ«mongodÊÇÈçºÎ½«client·¢À´µÄ²Ù×÷ÇëÇó½øÐÐת»»²¢½ø¶øÖ´ÐÐÏàÓ¦µÄcommandÖ¸ÁîµÄÄØ£¿ÎÒÃǽÓÏÂÀ´¼ÌÐø·ÖÎö¡£

֮ǰ¿´¹ýÎÒµÄÕâÆªÎÄÕµÄÅóÓÑ¿ÉÄÜ»¹ÓÐÓ¡Ïó£¬ÔÚmongodÆô¶¯Ö®ºó£¬»áÑ­»·ÕìÌýÖ¸Ïò¶Ë¿ÚÉϵÄÓû§(client)ÇëÇó£¬ÕâЩÇëÇóÔÚmongodÖб»¸Ä×°³ÉÁËmessageÔÚ¸÷¸ö¹¦ÄÜÀàÖд«µÝ¡£µ±Óû§·¢ËÍÒ»¸öcountÖ¸Áî²Ù×÷ʱ£¬Æä»áÔÚquery.cppÖÐÖ´ÐÐÏÂÃæ·½·¨£¨ÒÔcount²éѯָÁîµÄÖ´ÐÐÁ÷³ÌΪÀýÀ´½øÐзÖÎö£©£º

//query.cpp
const char *runQuery(Message& m, QueryMessage& q, CurOp& curop, Message &result) {
StringBuilder& ss = curop.debug().str;
//¹¹ÔìParsedQuery²éѯ¶ÔÏ󣬸öÔÏó°üÀ¨²éѯ¼Ç¼Êý×Ö£¬ÒÔ¼°¼ÇÂ¼Ìø×ªÆ«ÒÆÁ¿µÈÐÅÏ¢£¬
//ÕâЩֵ»áÔÚ·ÃÎÊ´ÅÅ̲éѯʱʹÓã¬Ó÷¨²Î¼û:query.cpp 662ÐеÄvirtual void _init()·½·¨
shared_ptr<ParsedQuery> pq_shared( new ParsedQuery(q) );
ParsedQuery& pq( *pq_shared );
......
//¶Ô²éѯÃüÁîÅжϣ¬Ö¸ÁîÐÎÈçabc.$cmd.findOne( { ismaster:1 } )
if ( pq.couldBeCommand() ) {//_nsÖаüÀ¨$cmd×Ö·û´®
BufBuilder bb;
bb.skip(sizeof(QueryResult));
BSONObjBuilder cmdResBuf;
//¶Ô²éѯȨÏÞÅжϣ¬²¢Ö´ÐÐÏàÓ¦²éѯָÁî
if ( runCommands(ns, jsobj, curop, bb, cmdResBuf, false, queryOptions) ) {
ss << " command: ";
jsobj.toString( ss );
curop.markCommand();
auto_ptr< QueryResult > qr;
qr.reset( (QueryResult *) bb.buf() );
bb.decouple();
qr->setResultFlagsToOk();
qr->len = bb.len();
ss << " reslen:" << bb.len();
qr->setOperation(opReply);
qr->cursorId = 0;
qr->startingFrom = 0;
qr->nReturned = 1;
result.setData( qr.release(), true );//ÉèÖ÷µ»Ø½á¹û
}
else {
uasserted(13530, "bad or malformed command request?");
}
return 0;
}
.....
}

ÉÏÃæ´úÂë¶Ô´«µÝÀ´µÄ²éѯÏûÏ¢QueryMessage£¨ÓйØÏûÏ¢»úÖÆ²Î¼ûÎÒµÄÕâÆªÎÄÕ£©½øÐзÖÎöÖ®ºó£¬Èç¹û·¢ÏÖÆäΪcommandʱ£¬Ö´ÐÐrunCommands·½·¨£º

//query.cpp   
bool runCommands(const char *ns, BSONObj& jsobj, CurOp& curop, BufBuilder &b, BSONObjBuilder& anObjBuilder, bool fromRepl, int queryOptions) {
try {
return _runCommands(ns, jsobj, b, anObjBuilder, fromRepl, queryOptions);
}
catch ( AssertionException& e ) {
e.getInfo().append( anObjBuilder , "assertion" , "assertionCode" );
}
curop.debug().str << " assertion ";
anObjBuilder.append("errmsg", "db assertion failure");
anObjBuilder.append("ok", 0.0);
BSONObj x = anObjBuilder.done();
b.appendBuf((void*) x.objdata(), x.objsize());
return true;
}

½Ó×ÅÆä»áÖ´ÐÐdbcommands.cppÖеÄ_runCommands()·½·¨

//dbcommands.cpp
bool _runCommands(const char *ns, BSONObj& _cmdobj, BufBuilder &b, BSONObjBuilder& anObjBuilder, bool fromRepl, int queryOptions) {
cc().curop()->ensureStarted();
string dbname = nsToDatabase( ns );
if( logLevel >= 1 )
log() << "run command " << ns << ' ' << _cmdobj << endl;
const char *p = strchr(ns, '.');
if ( !p ) return false;
//ÔٴνøÐÐcmdÅжϣ¬ÒÔÈ·¶¨ÊÇcommand
if ( strcmp(p, ".$cmd") != 0 ) return false;
BSONObj jsobj;
{
BSONElement e = _cmdobj.firstElement();
if ( e.type() == Object && string("query") == e.fieldName() ) {
jsobj = e.embeddedObject();
}
else {
jsobj = _cmdobj;
}
}
Client& client = cc();
bool ok = false;
BSONElement e = jsobj.firstElement();
//¸ù¾ÝcommandÃû³Æ´ÓmapÖÐÕÒ³öÏàÓ¦µÄcommand¶ÔÏó
Command * c = e.type() ? Command::findCommand( e.fieldName() ) : 0;
if ( c ) {
//Ö´ÐиöÔÏó
ok = execCommand( c , client , queryOptions , ns , jsobj , anObjBuilder , fromRepl );
}
else {
anObjBuilder.append("errmsg", str::stream() << "no such cmd: " << e.fieldName() );
anObjBuilder.append("bad cmd" , _cmdobj );
} // switch to bool, but wait a bit longer before switching?
// anObjBuilder.append("ok", ok);
anObjBuilder.append("ok", ok?1.0:0.0);
BSONObj x = anObjBuilder.done();
b.appendBuf((void*) x.objdata(), x.objsize()); return true;
}

ÉÏÃæ´úÂëÖ÷ÒªÊÇ´ÓmapÖÐÕÒ³öÏàÓ¦µÄcommand¶ÔÏ󣬲¢½«¸Ã¶ÔÏó¼°²Ù×÷ÃüÁî²ÎÊýºÍclient(ÓÃÓÚ»ñÈ¡ÆäÖеÄÈÏÖ¤ÐÅÏ¢£¬ÒÔÈ·¶¨ÆäÖ´ÐÐȨÏÞ)×÷Ϊ²ÎÊý£¬À´µ÷Óà execCommand·½·¨£º

//dbcommands.cpp
    bool execCommand( Command * c ,
                      Client& client , int queryOptions ,
                      const char *cmdns, BSONObj& cmdObj ,
                      BSONObjBuilder& result /*·µ»ØcommandÖ´Ðнá¹û*/,
                      bool fromRepl ) {

        string dbname = nsToDatabase( cmdns );

        AuthenticationInfo *ai = client.getAuthenticationInfo();
        
        if( c->adminOnly() /*Èç¹ûÐèÒªÓйÜÀíÌØÈ¨¿ª¿ÉÔËÐÐ*/
            && c->localHostOnlyIfNoAuth( cmdObj ) /*Ҫô±»ÑéÖ¤£¬ÒªÃ´Ö»ÔËÐÐÔÚ±¾µØ½Ó¿Ú*/
            && noauth && !ai->isLocalHost ) {//δÈÏÖ¤ ÇÒ ²»ÊÇÔÚ±¾µØÔËÐÐ
            result.append( "errmsg" ,
                           "unauthorized: this command must run from localhost when running db without auth" );
            log() << "command denied: " << cmdObj.toString() << endl;
            return false;
        }

        if ( c->adminOnly() && ! fromRepl && dbname != "admin" ) {
            result.append( "errmsg" ,  "access denied; use admin db" );
            log() << "command denied: " << cmdObj.toString() << endl;
            return false;
        }

        if ( cmdObj["help"].trueValue() ) {
            stringstream ss;
            ss << "help for: " << c->name << " ";
            c->help( ss );
            result.append( "help" , ss.str() );
            result.append( "lockType" , c->locktype() );
            return true;
        }

        bool canRunHere =
            isMaster( dbname.c_str() ) /*ÈçΪmaster¿â*/||
            c->slaveOk() /*Èç¹ûreplication pair µÄslaves¿ÉÒÔÔËÐÐÃüÁî*/||
            ( c->slaveOverrideOk() && ( queryOptions & QueryOption_SlaveOk ) ) ||
            fromRepl;

        if ( ! canRunHere ) {
            result.append( "errmsg" , "not master" );
            return false;
        }

        if ( c->adminOnly() )
            log( 2 ) << "command: " << cmdObj << endl;

        //È統ǰcommandÎÞÐëËøÊ±
        if ( c->locktype() == Command::NONE ) {
            // we also trust that this won't crash
            string errmsg;
            //ÔËÐе±Ç°command
            int ok = c->run( dbname , cmdObj , errmsg , result , fromRepl );
            if ( ! ok )
                result.append( "errmsg" , errmsg );
            return ok;
        }
        //ÅжÏÖ´Ðе±Ç°commandÊÇ·ñÐèÒª'Ð´Ëø'(ÿ¸öcommand×ÓÀà¶¼ÓиÃÊôÐÔ)£¬Ã¶¾Ù¶¨ÒåÈçÏÂ(command.h)£º
        //enum LockType { READ = -1/*¶Á*/ , NONE = 0 /*ÎÞËø*/, WRITE = 1 /*д*/};
        bool needWriteLock = c->locktype() == Command::WRITE;

        if ( ! needWriteLock ) {
            assert( ! c->logTheOp() );
        }

        mongolock lk( needWriteLock );//ÉùÃ÷Ëø¶ÔÏó
        Client::Context ctx( dbname , dbpath , &lk , c->requiresAuth() );

        try {
            string errmsg;
            //ÔËÐе±Ç°command(±¾ÎÄÖÐÌáµ½µÄcountÃüÁî)
            if ( ! c->run(dbname, cmdObj, errmsg, result, fromRepl ) ) {
                result.append( "errmsg" , errmsg );
                return false;
            }
        }
        catch ( DBException& e ) {
            stringstream ss;
            ss << "exception: " << e.what();
            result.append( "errmsg" , ss.str() );
            result.append( "code" , e.getCode() );
            return false;
        }

        if ( c->logTheOp() && ! fromRepl ) {
            logOp("c", cmdns, cmdObj);
        }

        return true;
    }

µ½ÕâÀÁ÷³Ì»ù±¾¾ÍÖ´ÐÐÍê±ÏÁË£¬Ö®ºóËü»á½«½á¹û´«¸øresult£¨Æä´«²ÎΪÒýÓÃÀàÐÍ£¬¼´£º"& result"·½Ê½£©.

×îºóÓÃÒ»ÕÅʱ¼äÐòÀ´´óÌ廨¹ËÒ»ÏÂÕâÒ»Á÷³Ì£º

ºÃÁË£¬½ñÌìµÄÄÚÈݵ½ÕâÀï¾Í¸æÒ»¶ÎÂäÁË¡£

   
2313 ´Îä¯ÀÀ       31
Ïà¹ØÎÄÕÂ

»ùÓÚEAµÄÊý¾Ý¿â½¨Ä£
Êý¾ÝÁ÷½¨Ä££¨EAÖ¸ÄÏ£©
¡°Êý¾Ýºþ¡±£º¸ÅÄî¡¢ÌØÕ÷¡¢¼Ü¹¹Óë°¸Àý
ÔÚÏßÉ̳ÇÊý¾Ý¿âϵͳÉè¼Æ ˼·+Ч¹û
 
Ïà¹ØÎĵµ

GreenplumÊý¾Ý¿â»ù´¡Åàѵ
MySQL5.1ÐÔÄÜÓÅ»¯·½°¸
ijµçÉÌÊý¾ÝÖÐ̨¼Ü¹¹Êµ¼ù
MySQL¸ßÀ©Õ¹¼Ü¹¹Éè¼Æ
Ïà¹Ø¿Î³Ì

Êý¾ÝÖÎÀí¡¢Êý¾Ý¼Ü¹¹¼°Êý¾Ý±ê×¼
MongoDBʵս¿Î³Ì
²¢·¢¡¢´óÈÝÁ¿¡¢¸ßÐÔÄÜÊý¾Ý¿âÉè¼ÆÓëÓÅ»¯
PostgreSQLÊý¾Ý¿âʵսÅàѵ
×îл¼Æ»®
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢ 6-12[ÏÃÃÅ]
È˹¤ÖÇÄÜ.»úÆ÷ѧϰTensorFlow 6-22[Ö±²¥]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 6-30[±±¾©]
ǶÈëʽÈí¼þ¼Ü¹¹-¸ß¼¶Êµ¼ù 7-9[±±¾©]
Óû§ÌåÑé¡¢Ò×ÓÃÐÔ²âÊÔÓëÆÀ¹À 7-25[Î÷°²]
ͼÊý¾Ý¿âÓë֪ʶͼÆ× 8-23[±±¾©]

MySQLË÷Òý±³ºóµÄÊý¾Ý½á¹¹
MySQLÐÔÄܵ÷ÓÅÓë¼Ü¹¹Éè¼Æ
SQL ServerÊý¾Ý¿â±¸·ÝÓë»Ö¸´
ÈÃÊý¾Ý¿â·ÉÆðÀ´ 10´óDB2ÓÅ»¯
oracleµÄÁÙʱ±í¿Õ¼äдÂú´ÅÅÌ
Êý¾Ý¿âµÄ¿çƽ̨Éè¼Æ


²¢·¢¡¢´óÈÝÁ¿¡¢¸ßÐÔÄÜÊý¾Ý¿â
¸ß¼¶Êý¾Ý¿â¼Ü¹¹Éè¼ÆÊ¦
HadoopÔ­ÀíÓëʵ¼ù
Oracle Êý¾Ý²Ö¿â
Êý¾Ý²Ö¿âºÍÊý¾ÝÍÚ¾ò
OracleÊý¾Ý¿â¿ª·¢Óë¹ÜÀí


GE Çø¿éÁ´¼¼ÊõÓëʵÏÖÅàѵ
º½Ìì¿Æ¹¤Ä³×Ó¹«Ë¾ Nodejs¸ß¼¶Ó¦Óÿª·¢
ÖÐÊ¢Òæ»ª ׿Խ¹ÜÀíÕß±ØÐë¾ß±¸µÄÎåÏîÄÜÁ¦
ijÐÅÏ¢¼¼Êõ¹«Ë¾ PythonÅàѵ
ij²©²ÊITϵͳ³§ÉÌ Ò×ÓÃÐÔ²âÊÔÓëÆÀ¹À
ÖйúÓÊ´¢ÒøÐÐ ²âÊÔ³ÉÊì¶ÈÄ£Ðͼ¯³É(TMMI)
ÖÐÎïÔº ²úÆ·¾­ÀíÓë²úÆ·¹ÜÀí