Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

SERVER-1292 For now, don't add a mongod as a shard if it's not empty.…

… Will allow that next.
  • Loading branch information...
commit 5a69c45341c23f654832f948febf793c6896e6b4 1 parent 6231026
Alberto Lerner authored
View
12 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();
View
3  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;
}
View
44 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;
}
View
5 s/grid.h
@@ -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;
Please sign in to comment.
Something went wrong with that request. Please try again.