summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberto Lerner <alerner@10gen.com>2010-07-28 14:24:55 -0400
committerAlberto Lerner <alerner@10gen.com>2010-07-28 14:24:55 -0400
commitbceacf2544acfb6c3509ca8db791e90fe41c8599 (patch)
tree5c210716aa3c6911c96f55d8a6370015a76b4d5a
parent0e82f323cc1be77401021486f459e14cef359faa (diff)
downloadmongo-bceacf2544acfb6c3509ca8db791e90fe41c8599.tar.gz
SERVER-1292 A bit more prep, separate grid.{h,cpp} from config
-rw-r--r--SConstruct2
-rw-r--r--s/balance.cpp1
-rw-r--r--s/commands_admin.cpp1
-rw-r--r--s/commands_public.cpp1
-rw-r--r--s/config.cpp199
-rw-r--r--s/config.h75
-rw-r--r--s/grid.cpp226
-rw-r--r--s/grid.h103
-rw-r--r--s/request.cpp1
-rw-r--r--s/server.cpp1
-rw-r--r--s/strategy.cpp2
11 files changed, 339 insertions, 273 deletions
diff --git a/SConstruct b/SConstruct
index 7e96a50cdb9..04fd6bd742c 100644
--- a/SConstruct
+++ b/SConstruct
@@ -456,7 +456,7 @@ else:
coreServerFiles += scriptingFiles
-coreShardFiles = [ "s/config.cpp" , "s/chunk.cpp" , "s/shard.cpp" , "s/shardkey.cpp" ]
+coreShardFiles = [ "s/config.cpp" , "s/grid.cpp" , "s/chunk.cpp" , "s/shard.cpp" , "s/shardkey.cpp" ]
shardServerFiles = coreShardFiles + Glob( "s/strategy*.cpp" ) + [ "s/commands_admin.cpp" , "s/commands_public.cpp" , "s/request.cpp" , "s/cursors.cpp" , "s/server.cpp" , "s/config_migrate.cpp" , "s/s_only.cpp" , "s/stats.cpp" , "s/balance.cpp" , "s/balancer_policy.cpp" , "db/cmdline.cpp" ]
serverOnlyFiles += coreShardFiles + [ "s/d_logic.cpp" , "s/d_writeback.cpp" , "s/d_migrate.cpp" , "s/d_state.cpp" , "s/d_split.cpp" , "client/distlock_test.cpp" ]
diff --git a/s/balance.cpp b/s/balance.cpp
index 2da5689db58..f79e1d8e060 100644
--- a/s/balance.cpp
+++ b/s/balance.cpp
@@ -28,6 +28,7 @@
#include "shard.h"
#include "config.h"
#include "chunk.h"
+#include "grid.h"
namespace mongo {
diff --git a/s/commands_admin.cpp b/s/commands_admin.cpp
index 5585db8ea99..af50422cba4 100644
--- a/s/commands_admin.cpp
+++ b/s/commands_admin.cpp
@@ -38,6 +38,7 @@
#include "config.h"
#include "chunk.h"
+#include "grid.h"
#include "strategy.h"
#include "stats.h"
diff --git a/s/commands_public.cpp b/s/commands_public.cpp
index 0197c38a7bc..3dbc8ad5112 100644
--- a/s/commands_public.cpp
+++ b/s/commands_public.cpp
@@ -28,6 +28,7 @@
#include "config.h"
#include "chunk.h"
#include "strategy.h"
+#include "grid.h"
namespace mongo {
diff --git a/s/config.cpp b/s/config.cpp
index 24ef4087dce..e6bb48870c4 100644
--- a/s/config.cpp
+++ b/s/config.cpp
@@ -28,6 +28,7 @@
#include "server.h"
#include "config.h"
#include "chunk.h"
+#include "grid.h"
namespace mongo {
@@ -236,7 +237,7 @@ namespace mongo {
return true;
}
-
+
void DBConfig::_save(){
ScopedDbConnection conn( configServer.modelServer() );
@@ -384,201 +385,6 @@ namespace mongo {
}
}
- /* --- Grid --- */
-
- DBConfigPtr Grid::getDBConfig( string database , bool create ){
- {
- string::size_type i = database.find( "." );
- if ( i != string::npos )
- database = database.substr( 0 , i );
- }
-
- if ( database == "config" )
- return configServerPtr;
-
- scoped_lock l( _lock );
-
- DBConfigPtr& cc = _databases[database];
- if ( !cc ){
- cc.reset(new DBConfig( database ));
- if ( ! cc->load() ){
- if ( create ){
- // note here that cc->primary == 0.
- log() << "couldn't find database [" << database << "] in config db" << endl;
-
- { // lets check case
- ScopedDbConnection conn( configServer.modelServer() );
- BSONObjBuilder b;
- b.appendRegex( "_id" , (string)"^" + database + "$" , "i" );
- BSONObj d = conn->findOne( ShardNS::database , b.obj() );
- conn.done();
-
- if ( ! d.isEmpty() ){
- cc.reset();
- stringstream ss;
- ss << "can't have 2 databases that just differ on case "
- << " have: " << d["_id"].String()
- << " want to add: " << database;
-
- uasserted( DatabaseDifferCaseCode ,ss.str() );
- }
- }
-
- if ( database == "admin" )
- cc->_primary = configServer.getPrimary();
- else
- cc->_primary = Shard::pick();
-
- if ( cc->_primary.ok() ){
- cc->_save();
- log() << "\t put [" << database << "] on: " << cc->_primary.toString() << endl;
- }
- else {
- cc.reset();
- log() << "\t can't find a shard to put new db on" << endl;
- uasserted( 10185 , "can't find a shard to put new db on" );
- }
- }
- else {
- cc.reset();
- }
- }
-
- }
-
- return cc;
- }
-
- void Grid::removeDB( string database ){
- uassert( 10186 , "removeDB expects db name" , database.find( '.' ) == string::npos );
- scoped_lock l( _lock );
- _databases.erase( database );
-
- }
-
- bool Grid::allowLocalHost() const {
- return _allowLocalShard;
- }
-
- void Grid::setAllowLocalHost( bool allow ){
- _allowLocalShard = allow;
- }
-
- bool Grid::addShard( string* name , const string& host , long long maxSize , string* errMsg ){
- // errMsg is required but name is optional
- DEV assert( errMsg );
- string nameInternal;
- if ( ! name ) {
- name = &nameInternal;
- }
-
- // check whether host exists and is operative
- try {
- ScopedDbConnection newShardConn( host );
- newShardConn->getLastError();
- newShardConn.done();
- }
- catch ( DBException& e ){
- ostringstream ss;
- ss << "couldn't connect to new shard ";
- ss << e.what();
- *errMsg = ss.str();
- return false;
- }
-
- // if a name for a shard wasn't provided, pick one.
- if ( name->empty() && ! _getNewShardName( name ) ){
- *errMsg = "error generating new shard name";
- return false;
- }
-
- // build the ConfigDB shard document.
- BSONObjBuilder b;
- b.append( "_id" , *name );
- b.append( "host" , host );
- if ( maxSize > 0 ){
- b.append( ShardFields::maxSize.name() , maxSize );
- }
- BSONObj shardDoc = b.obj();
-
- {
- ScopedDbConnection conn( configServer.getPrimary() );
-
- // check whether this host:port is already a known shard
- BSONObj old = conn->findOne( ShardNS::shard , BSON( "host" << host ) );
- if ( ! old.isEmpty() ){
- *errMsg = "host already used";
- conn.done();
- return false;
- }
-
- log() << "going to add shard: " << shardDoc << endl;
-
- conn->insert( ShardNS::shard , shardDoc );
- *errMsg = conn->getLastError();
- if ( ! errMsg->empty() ){
- log() << "error adding shard: " << shardDoc << " err: " << *errMsg << endl;
- return false;
- }
-
- conn.done();
- }
-
- Shard::reloadShardInfo();
- return true;
- }
-
- bool Grid::knowAboutShard( const string& name ) const{
- ShardConnection conn( configServer.getPrimary() , "" );
- BSONObj shard = conn->findOne( ShardNS::shard , BSON( "host" << name ) );
- conn.done();
- return ! shard.isEmpty();
- }
-
- bool Grid::_getNewShardName( string* name ) const{
- DEV assert( name );
-
- bool ok = false;
- int count = 0;
-
- ShardConnection conn( configServer.getPrimary() , "" );
- BSONObj o = conn->findOne( ShardNS::shard , Query( fromjson ( "{_id: /^shard/}" ) ).sort( BSON( "_id" << -1 ) ) );
- if ( ! o.isEmpty() ) {
- string last = o["_id"].String();
- istringstream is( last.substr( 5 ) );
- is >> count;
- count++;
- }
- if (count < 9999) {
- stringstream ss;
- ss << "shard" << setfill('0') << setw(4) << count;
- *name = ss.str();
- ok = true;
- }
- conn.done();
-
- return ok;
- }
-
- bool Grid::shouldBalance() const {
- ShardConnection conn( configServer.getPrimary() , "" );
-
- // look for the stop balancer marker
- BSONObj stopMarker = conn->findOne( ShardNS::settings, BSON( "_id" << "balancer" << "stopped" << true ) );
- conn.done();
- return stopMarker.isEmpty();
- }
-
- unsigned long long Grid::getNextOpTime() const {
- ScopedDbConnection conn( configServer.getPrimary() );
-
- BSONObj result;
- massert( 10421 , "getoptime failed" , conn->simpleCommand( "admin" , &result , "getoptime" ) );
- conn.done();
-
- return result["optime"]._numberLong();
- }
-
/* --- ConfigServer ---- */
ConfigServer::ConfigServer() : DBConfig( "config" ){
@@ -761,6 +567,5 @@ namespace mongo {
DBConfigPtr configServerPtr (new ConfigServer());
ConfigServer& configServer = dynamic_cast<ConfigServer&>(*configServerPtr);
- Grid grid;
}
diff --git a/s/config.h b/s/config.h
index cbefe7283ea..c1767743acd 100644
--- a/s/config.h
+++ b/s/config.h
@@ -51,7 +51,6 @@ namespace mongo {
static BSONField<long long> currSize;
};
- class Grid;
class ConfigServer;
class DBConfig;
@@ -59,7 +58,6 @@ namespace mongo {
extern DBConfigPtr configServerPtr;
extern ConfigServer& configServer;
- extern Grid grid;
class ChunkManager;
typedef shared_ptr<ChunkManager> ChunkManagerPtr;
@@ -192,82 +190,9 @@ namespace mongo {
mongo::mutex _lock; // TODO: change to r/w lock ??
- friend class Grid;
friend class ChunkManager;
};
- /**
- * stores meta-information about the grid
- * TODO: used shard_ptr for DBConfig pointers
- */
- class Grid {
- public:
- Grid() : _lock( "Grid" ) , _allowLocalShard( true ) { }
-
- /**
- * gets the config the db.
- * will return an empty DBConfig if not in db already
- */
- DBConfigPtr getDBConfig( string ns , bool create=true );
-
- /**
- * removes db entry.
- * on next getDBConfig call will fetch from db
- */
- void removeDB( string db );
-
- /**
- * @return true if shards and config servers are allowed to use 'localhost' in address
- */
- bool allowLocalHost() const;
-
- /**
- * @param whether to allow shards and config servers to use 'localhost' in address
- */
- void setAllowLocalHost( bool allow );
-
- /**
- *
- * addShard will create a new shard in the grid. It expects a mongod process to be runing
- * on the provided address.
- * TODO - add the mongod's databases to the grid
- *
- * @param name is an optional string with the name of the shard. if ommited, grid will
- * generate one and update the parameter.
- * @param host is the complete address of the machine where the shard will be
- * @param maxSize is the optional space quota in bytes. Zeros means there's no limitation to
- * space usage
- * @param errMsg is the error description in case the operation failed.
- * @return true if shard was successfully added.
- */
- bool addShard( string* name , const string& host , long long maxSize , string* errMsg );
-
- /**
- * @return true if the config database knows about a host 'name'
- */
- bool knowAboutShard( const string& name ) const;
-
- /**
- * @return true if the chunk balancing functionality is enabled
- */
- bool shouldBalance() const;
-
- unsigned long long getNextOpTime() const;
-
- private:
- mongo::mutex _lock; // protects _databases; TODO: change to r/w lock ??
- map<string, DBConfigPtr > _databases; // maps ns to DBConfig's
- bool _allowLocalShard; // can 'localhost' be used in shard addresses?
-
- /**
- * @param name is the chose name for the shard. Parameter is mandatory.
- * @return true if it managed to generate a shard name. May return false if (currently)
- * 10000 shard
- */
- bool _getNewShardName( string* name ) const;
-
- };
-
class ConfigServer : public DBConfig {
public:
diff --git a/s/grid.cpp b/s/grid.cpp
new file mode 100644
index 00000000000..e1e6c4b40a5
--- /dev/null
+++ b/s/grid.cpp
@@ -0,0 +1,226 @@
+// grid.cpp
+
+/**
+* Copyright (C) 2010 10gen Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "pch.h"
+
+#include <iomanip>
+
+#include "../client/connpool.h"
+
+#include "grid.h"
+#include "shard.h"
+
+namespace mongo {
+
+ DBConfigPtr Grid::getDBConfig( string database , bool create ){
+ {
+ string::size_type i = database.find( "." );
+ if ( i != string::npos )
+ database = database.substr( 0 , i );
+ }
+
+ if ( database == "config" )
+ return configServerPtr;
+
+ scoped_lock l( _lock );
+
+ DBConfigPtr& cc = _databases[database];
+ if ( !cc ){
+ cc.reset(new DBConfig( database ));
+ if ( ! cc->load() ){
+ if ( create ){
+ // note here that cc->primary == 0.
+ log() << "couldn't find database [" << database << "] in config db" << endl;
+
+ { // lets check case
+ ScopedDbConnection conn( configServer.modelServer() );
+ BSONObjBuilder b;
+ b.appendRegex( "_id" , (string)"^" + database + "$" , "i" );
+ BSONObj d = conn->findOne( ShardNS::database , b.obj() );
+ conn.done();
+
+ if ( ! d.isEmpty() ){
+ cc.reset();
+ stringstream ss;
+ ss << "can't have 2 databases that just differ on case "
+ << " have: " << d["_id"].String()
+ << " want to add: " << database;
+
+ uasserted( DatabaseDifferCaseCode ,ss.str() );
+ }
+ }
+
+ Shard primary;
+ if ( database == "admin" )
+ primary = configServer.getPrimary();
+ else
+ primary = Shard::pick();
+
+ if ( primary.ok() ){
+ cc->setPrimary( primary.getName() ); // saves 'cc' to configDB
+ log() << "\t put [" << database << "] on: " << primary << endl;
+ }
+ else {
+ cc.reset();
+ log() << "\t can't find a shard to put new db on" << endl;
+ uasserted( 10185 , "can't find a shard to put new db on" );
+ }
+ }
+ else {
+ cc.reset();
+ }
+ }
+
+ }
+
+ return cc;
+ }
+
+ void Grid::removeDB( string database ){
+ uassert( 10186 , "removeDB expects db name" , database.find( '.' ) == string::npos );
+ scoped_lock l( _lock );
+ _databases.erase( database );
+
+ }
+
+ bool Grid::allowLocalHost() const {
+ return _allowLocalShard;
+ }
+
+ void Grid::setAllowLocalHost( bool allow ){
+ _allowLocalShard = allow;
+ }
+
+ bool Grid::addShard( string* name , const string& host , long long maxSize , string* errMsg ){
+ // errMsg is required but name is optional
+ DEV assert( errMsg );
+ string nameInternal;
+ if ( ! name ) {
+ name = &nameInternal;
+ }
+
+ // check whether host exists and is operative
+ try {
+ ScopedDbConnection newShardConn( host );
+ newShardConn->getLastError();
+ newShardConn.done();
+ }
+ catch ( DBException& e ){
+ ostringstream ss;
+ ss << "couldn't connect to new shard ";
+ ss << e.what();
+ *errMsg = ss.str();
+ return false;
+ }
+
+ // if a name for a shard wasn't provided, pick one.
+ if ( name->empty() && ! _getNewShardName( name ) ){
+ *errMsg = "error generating new shard name";
+ return false;
+ }
+
+ // build the ConfigDB shard document.
+ BSONObjBuilder b;
+ b.append( "_id" , *name );
+ b.append( "host" , host );
+ if ( maxSize > 0 ){
+ b.append( ShardFields::maxSize.name() , maxSize );
+ }
+ BSONObj shardDoc = b.obj();
+
+ {
+ ScopedDbConnection conn( configServer.getPrimary() );
+
+ // check whether this host:port is already a known shard
+ BSONObj old = conn->findOne( ShardNS::shard , BSON( "host" << host ) );
+ if ( ! old.isEmpty() ){
+ *errMsg = "host already used";
+ conn.done();
+ return false;
+ }
+
+ log() << "going to add shard: " << shardDoc << endl;
+
+ conn->insert( ShardNS::shard , shardDoc );
+ *errMsg = conn->getLastError();
+ if ( ! errMsg->empty() ){
+ log() << "error adding shard: " << shardDoc << " err: " << *errMsg << endl;
+ return false;
+ }
+
+ conn.done();
+ }
+
+ Shard::reloadShardInfo();
+ return true;
+ }
+
+ bool Grid::knowAboutShard( const string& name ) const{
+ ShardConnection conn( configServer.getPrimary() , "" );
+ BSONObj shard = conn->findOne( ShardNS::shard , BSON( "host" << name ) );
+ conn.done();
+ return ! shard.isEmpty();
+ }
+
+ bool Grid::_getNewShardName( string* name ) const{
+ DEV assert( name );
+
+ bool ok = false;
+ int count = 0;
+
+ ShardConnection conn( configServer.getPrimary() , "" );
+ BSONObj o = conn->findOne( ShardNS::shard , Query( fromjson ( "{_id: /^shard/}" ) ).sort( BSON( "_id" << -1 ) ) );
+ if ( ! o.isEmpty() ) {
+ string last = o["_id"].String();
+ istringstream is( last.substr( 5 ) );
+ is >> count;
+ count++;
+ }
+ if (count < 9999) {
+ stringstream ss;
+ ss << "shard" << setfill('0') << setw(4) << count;
+ *name = ss.str();
+ ok = true;
+ }
+ conn.done();
+
+ return ok;
+ }
+
+ bool Grid::shouldBalance() const {
+ ShardConnection conn( configServer.getPrimary() , "" );
+
+ // look for the stop balancer marker
+ BSONObj stopMarker = conn->findOne( ShardNS::settings, BSON( "_id" << "balancer" << "stopped" << true ) );
+ conn.done();
+ return stopMarker.isEmpty();
+ }
+
+ unsigned long long Grid::getNextOpTime() const {
+ ScopedDbConnection conn( configServer.getPrimary() );
+
+ BSONObj result;
+ massert( 10421 , "getoptime failed" , conn->simpleCommand( "admin" , &result , "getoptime" ) );
+ conn.done();
+
+ return result["optime"]._numberLong();
+ }
+
+ Grid grid;
+
+}
diff --git a/s/grid.h b/s/grid.h
new file mode 100644
index 00000000000..2ebe60e3761
--- /dev/null
+++ b/s/grid.h
@@ -0,0 +1,103 @@
+// grid.h
+
+/**
+* Copyright (C) 2010 10gen Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include "pch.h"
+
+#include "../util/concurrency/mutex.h"
+
+#include "config.h" // DBConfigPtr
+
+namespace mongo {
+
+ /**
+ * stores meta-information about the grid
+ * TODO: used shard_ptr for DBConfig pointers
+ */
+ class Grid {
+ public:
+ Grid() : _lock( "Grid" ) , _allowLocalShard( true ) { }
+
+ /**
+ * gets the config the db.
+ * will return an empty DBConfig if not in db already
+ */
+ DBConfigPtr getDBConfig( string ns , bool create=true );
+
+ /**
+ * removes db entry.
+ * on next getDBConfig call will fetch from db
+ */
+ void removeDB( string db );
+
+ /**
+ * @return true if shards and config servers are allowed to use 'localhost' in address
+ */
+ bool allowLocalHost() const;
+
+ /**
+ * @param whether to allow shards and config servers to use 'localhost' in address
+ */
+ void setAllowLocalHost( bool allow );
+
+ /**
+ *
+ * addShard will create a new shard in the grid. It expects a mongod process to be runing
+ * on the provided address.
+ * TODO - add the mongod's databases to the grid
+ *
+ * @param name is an optional string with the name of the shard. if ommited, grid will
+ * generate one and update the parameter.
+ * @param host is the complete address of the machine where the shard will be
+ * @param maxSize is the optional space quota in bytes. Zeros means there's no limitation to
+ * space usage
+ * @param errMsg is the error description in case the operation failed.
+ * @return true if shard was successfully added.
+ */
+ bool addShard( string* name , const string& host , long long maxSize , string* errMsg );
+
+ /**
+ * @return true if the config database knows about a host 'name'
+ */
+ bool knowAboutShard( const string& name ) const;
+
+ /**
+ * @return true if the chunk balancing functionality is enabled
+ */
+ bool shouldBalance() const;
+
+ unsigned long long getNextOpTime() const;
+
+ private:
+ mongo::mutex _lock; // protects _databases; TODO: change to r/w lock ??
+ map<string, DBConfigPtr > _databases; // maps ns to DBConfig's
+ bool _allowLocalShard; // can 'localhost' be used in shard addresses?
+
+ /**
+ * @param name is the chose name for the shard. Parameter is mandatory.
+ * @return true if it managed to generate a shard name. May return false if (currently)
+ * 10000 shard
+ */
+ bool _getNewShardName( string* name ) const;
+
+ };
+
+ extern Grid grid;
+
+} // namespace mongo
diff --git a/s/request.cpp b/s/request.cpp
index f8877573854..e65aa1532f0 100644
--- a/s/request.cpp
+++ b/s/request.cpp
@@ -33,6 +33,7 @@
#include "chunk.h"
#include "stats.h"
#include "cursors.h"
+#include "grid.h"
namespace mongo {
diff --git a/s/server.cpp b/s/server.cpp
index 0c78618aaea..df6b082d335 100644
--- a/s/server.cpp
+++ b/s/server.cpp
@@ -30,6 +30,7 @@
#include "config.h"
#include "chunk.h"
#include "balance.h"
+#include "grid.h"
namespace mongo {
diff --git a/s/strategy.cpp b/s/strategy.cpp
index b32ecb5c242..b3c8f5b3b5c 100644
--- a/s/strategy.cpp
+++ b/s/strategy.cpp
@@ -21,7 +21,9 @@
#include "../util/background.h"
#include "../client/connpool.h"
#include "../db/commands.h"
+
#include "server.h"
+#include "grid.h"
namespace mongo {