diff options
-rw-r--r-- | s/commands_admin.cpp | 66 | ||||
-rw-r--r-- | s/shard.cpp | 32 | ||||
-rw-r--r-- | s/shard.h | 7 |
3 files changed, 105 insertions, 0 deletions
diff --git a/s/commands_admin.cpp b/s/commands_admin.cpp index be8233801ea..124c7a4f0bd 100644 --- a/s/commands_admin.cpp +++ b/s/commands_admin.cpp @@ -825,5 +825,71 @@ namespace mongo { } cmdGetLastError; } + + class CmdListDatabases : public Command { + public: + CmdListDatabases() : Command("listDatabases") {} + + virtual bool logTheOp() { return false; } + virtual bool slaveOk() const { return true; } + virtual bool slaveOverrideOk() { return true; } + virtual bool adminOnly() const { return true; } + virtual LockType locktype() const { return NONE; } + virtual void help( stringstream& help ) const { help << "list databases on cluster"; } + + bool run(const char *ns, BSONObj& jsobj, string& errmsg, BSONObjBuilder& result, bool /*fromRepl*/) { + list<Shard> shards; + Shard::getAllShards( shards ); + + map<string,long long> sizes; + map< string,shared_ptr<BSONObjBuilder> > dbShardInfo; + + for ( list<Shard>::iterator i=shards.begin(); i!=shards.end(); i++ ){ + Shard s = *i; + BSONObj x = s.runCommand( "admin" , "listDatabases" ); + cout << s.toString() << "\t" << x.jsonString() << endl; + BSONObjIterator j( x["databases"].Obj() ); + while ( j.more() ){ + BSONObj theDB = j.next().Obj(); + + string name = theDB["name"].String(); + long long size = theDB["sizeOnDisk"].numberLong(); + + long long& totalSize = sizes[name]; + if ( size == 1 ){ + if ( totalSize <= 1 ) + totalSize = 1; + } + else + totalSize += size; + + shared_ptr<BSONObjBuilder>& bb = dbShardInfo[name]; + if ( ! bb.get() ) + bb.reset( new BSONObjBuilder() ); + bb->appendNumber( s.getName() , size ); + } + + } + + BSONArrayBuilder bb( result.subarrayStart( "databases" ) ); + for ( map<string,long long>::iterator i=sizes.begin(); i!=sizes.end(); ++i ){ + string name = i->first; + long long size = i->second; + + BSONObjBuilder temp; + temp.append( "name" , name ); + temp.appendNumber( "size" , size ); + temp.appendBool( "empty" , size == 1 ); + temp.append( "shards" , dbShardInfo[name]->obj() ); + + bb.append( temp.obj() ); + } + bb.done(); + + return 1; + } + + } cmdListDatabases; + } // namespace mongo diff --git a/s/shard.cpp b/s/shard.cpp index aa20f1778d7..666375af588 100644 --- a/s/shard.cpp +++ b/s/shard.cpp @@ -19,6 +19,7 @@ #include "pch.h" #include "shard.h" #include "config.h" +#include <set> namespace mongo { @@ -72,6 +73,18 @@ namespace mongo { _lookup[addr] = s; } + void getAllShards( list<Shard>& all ){ + scoped_lock lk( _mutex ); + std::set<string> seen; + for ( map<string,Shard>::iterator i = _lookup.begin(); i!=_lookup.end(); ++i ){ + Shard s = i->second; + if ( seen.count( s.getName() ) ) + continue; + seen.insert( s.getName() ); + all.push_back( s ); + } + } + private: map<string,Shard> _lookup; mongo::mutex _mutex; @@ -91,4 +104,23 @@ namespace mongo { _name = s._name; _addr = s._addr; } + + void Shard::getAllShards( list<Shard>& all ){ + staticShardInfo.getAllShards( all ); + } + + + BSONObj Shard::runCommand( const string& db , const BSONObj& cmd ){ + ShardConnection conn( this ); + BSONObj res; + bool ok = conn->runCommand( db , cmd , res ); + if ( ! ok ){ + stringstream ss; + ss << "runCommand (" << cmd << ") on shard (" << _name << ") failed : " << res; + throw UserException( 13136 , ss.str() ); + } + res = res.getOwned(); + conn.done(); + return res; + } } diff --git a/s/shard.h b/s/shard.h index 3ff171186fb..8a02f63a7c8 100644 --- a/s/shard.h +++ b/s/shard.h @@ -99,6 +99,13 @@ namespace mongo { bool ok() const { return _addr.size() > 0 && _addr.size() > 0; } + + BSONObj runCommand( const string& db , const string& simple ){ + return runCommand( db , BSON( simple << 1 ) ); + } + BSONObj runCommand( const string& db , const BSONObj& cmd ); + + static void getAllShards( list<Shard>& all ); static Shard EMPTY; |