diff options
author | Alberto Lerner <alerner@10gen.com> | 2010-07-30 13:21:39 -0400 |
---|---|---|
committer | Alberto Lerner <alerner@10gen.com> | 2010-07-30 13:21:39 -0400 |
commit | 5a69c45341c23f654832f948febf793c6896e6b4 (patch) | |
tree | a1b989c505f6dd27e4f5534e7b6caf2c02fc4edb | |
parent | 62310262e6f4db58d175c131ed51d8e9ebd897b4 (diff) | |
download | mongo-5a69c45341c23f654832f948febf793c6896e6b4.tar.gz |
SERVER-1292 For now, don't add a mongod as a shard if it's not empty. Will allow that next.
-rw-r--r-- | jstests/sharding/addshard1.js | 12 | ||||
-rw-r--r-- | s/commands_admin.cpp | 3 | ||||
-rw-r--r-- | s/grid.cpp | 44 | ||||
-rw-r--r-- | s/grid.h | 5 |
4 files changed, 61 insertions, 3 deletions
diff --git a/jstests/sharding/addshard1.js b/jstests/sharding/addshard1.js new file mode 100644 index 00000000000..5e299770fff --- /dev/null +++ b/jstests/sharding/addshard1.js @@ -0,0 +1,12 @@ +s = new ShardingTest( "add_shard1", 1 ); + +assert.eq( 1, s.config.shards.count(), "initial server count wrong" ); + +// create a shard and add a database; a non-empty mongod should not be accepted as a shard +conn = startMongodTest( 29000 ); +db = conn.getDB( "test" ); +db.foo.save( {a:1} ); +assert( ! s.admin.runCommand( { addshard: "localhost:29000" } ).ok, "accepted non-empty shard" ); + +stopMongod( 29000 ); +s.stop();
\ No newline at end of file diff --git a/s/commands_admin.cpp b/s/commands_admin.cpp index af50422cba4..de47fd4a51b 100644 --- a/s/commands_admin.cpp +++ b/s/commands_admin.cpp @@ -620,6 +620,7 @@ namespace mongo { if ( shardAddr.isLocalHost() != grid.allowLocalHost() ){ errmsg = "can't use localhost as a shard since all shards need to communicate. " "either use all shards and configdbs in localhost or all in actual IPs " ; + log() << "addshard request " << cmdObj << " failed: attempt to mix localhosts and IPs" << endl; return false; } @@ -639,7 +640,7 @@ namespace mongo { } if ( ! grid.addShard( &name , shardAddr.toString() , maxSize , &errmsg ) ){ - // addShard filled errmsg + log() << "addshard request " << cmdObj << " failed: " << errmsg << endl; return false; } diff --git a/s/grid.cpp b/s/grid.cpp index e1e6c4b40a5..c3d8e3ad7a0 100644 --- a/s/grid.cpp +++ b/s/grid.cpp @@ -21,6 +21,7 @@ #include <iomanip> #include "../client/connpool.h" +#include "../util/stringutils.h" #include "grid.h" #include "shard.h" @@ -118,6 +119,40 @@ namespace mongo { try { ScopedDbConnection newShardConn( host ); newShardConn->getLastError(); + + // get the shard's local db's listing + BSONObj res; + bool ok = newShardConn->runCommand( "admin" , BSON( "listDatabases" << 1 ) , res ); + if ( !ok ){ + ostringstream ss; + ss << "failed listing " << host << " databases:" << res; + *errMsg = ss.str(); + newShardConn.done(); + return false; + } + + vector<string> dbNames; + BSONObjIterator i( res["databases"].Obj() ); + while ( i.more() ){ + BSONObj dbEntry = i.next().Obj(); + const string& dbName = dbEntry["name"].String(); + if ( ! _isSpecialLocalDB( dbName ) ){ + dbNames.push_back( dbName ); + } + } + + // TODO (within SERVER-1292) If the databases aren't duplicate, add them to the grid + if ( ! dbNames.empty() ){ + string dbConcat; + joinStringDelim( dbNames, &dbConcat , ',' ); + ostringstream ss; + ss << "cannot add shard " << host << " that has local databases: " << dbConcat; + *errMsg = ss.str(); + + newShardConn.done(); + return false; + } + newShardConn.done(); } catch ( DBException& e ){ @@ -134,7 +169,7 @@ namespace mongo { return false; } - // build the ConfigDB shard document. + // build the ConfigDB shard document BSONObjBuilder b; b.append( "_id" , *name ); b.append( "host" , host ); @@ -146,7 +181,7 @@ namespace mongo { { ScopedDbConnection conn( configServer.getPrimary() ); - // check whether this host:port is already a known shard + // check whether this host:port is not an already a known shard BSONObj old = conn->findOne( ShardNS::shard , BSON( "host" << host ) ); if ( ! old.isEmpty() ){ *errMsg = "host already used"; @@ -160,6 +195,7 @@ namespace mongo { *errMsg = conn->getLastError(); if ( ! errMsg->empty() ){ log() << "error adding shard: " << shardDoc << " err: " << *errMsg << endl; + conn.done(); return false; } @@ -221,6 +257,10 @@ namespace mongo { return result["optime"]._numberLong(); } + bool Grid::_isSpecialLocalDB( const string& dbName ){ + return ( dbName == "local" ) || ( dbName == "admin" ) || ( dbName == "config" ); + } + Grid grid; } @@ -94,6 +94,11 @@ namespace mongo { */ bool _getNewShardName( string* name ) const; + /** + * @return whether a give dbname is used for shard "local" databases (e.g., admin or local) + */ + static bool _isSpecialLocalDB( const string& dbName ); + }; extern Grid grid; |