summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--s/commands_admin.cpp66
-rw-r--r--s/shard.cpp32
-rw-r--r--s/shard.h7
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;