diff options
-rw-r--r-- | src/mongo/s/chunk_diff-inl.h | 1 | ||||
-rw-r--r-- | src/mongo/s/chunk_diff.h | 1 | ||||
-rw-r--r-- | src/mongo/s/client/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/s/client/shard.cpp | 278 | ||||
-rw-r--r-- | src/mongo/s/client/shard.h | 35 | ||||
-rw-r--r-- | src/mongo/s/client/shard_registry.cpp | 284 | ||||
-rw-r--r-- | src/mongo/s/client/shard_registry.h | 98 | ||||
-rw-r--r-- | src/mongo/s/config.cpp | 16 | ||||
-rw-r--r-- | src/mongo/s/config.h | 9 |
9 files changed, 305 insertions, 418 deletions
diff --git a/src/mongo/s/chunk_diff-inl.h b/src/mongo/s/chunk_diff-inl.h index 8ace994416a..3ef4cc1adcd 100644 --- a/src/mongo/s/chunk_diff-inl.h +++ b/src/mongo/s/chunk_diff-inl.h @@ -30,7 +30,6 @@ #pragma once -#include "mongo/client/dbclientinterface.h" #include "mongo/logger/log_severity.h" #include "mongo/logger/logger.h" #include "mongo/logger/logstream_builder.h" diff --git a/src/mongo/s/chunk_diff.h b/src/mongo/s/chunk_diff.h index 0200fd68ff6..3551381cce7 100644 --- a/src/mongo/s/chunk_diff.h +++ b/src/mongo/s/chunk_diff.h @@ -38,7 +38,6 @@ namespace mongo { class ChunkType; class CatalogManager; - class Query; /** * This class manages and applies diffs from partial config server data reloads. Because the diff --git a/src/mongo/s/client/SConscript b/src/mongo/s/client/SConscript index 725cee5d910..0b976cc340a 100644 --- a/src/mongo/s/client/SConscript +++ b/src/mongo/s/client/SConscript @@ -8,7 +8,6 @@ env.Library( 'dbclient_multi_command.cpp', 'shard.cpp', 'shard_connection.cpp', - 'shard_registry.cpp', ], LIBDEPS=[ '$BUILD_DIR/mongo/client/clientdriver', diff --git a/src/mongo/s/client/shard.cpp b/src/mongo/s/client/shard.cpp index a08a1012dad..3f88e3e1ccd 100644 --- a/src/mongo/s/client/shard.cpp +++ b/src/mongo/s/client/shard.cpp @@ -45,20 +45,264 @@ #include "mongo/db/auth/privilege.h" #include "mongo/db/commands.h" #include "mongo/db/jsobj.h" -#include "mongo/s/client/shard_registry.h" +#include "mongo/s/catalog/catalog_manager.h" +#include "mongo/s/catalog/type_shard.h" +#include "mongo/s/grid.h" #include "mongo/util/log.h" namespace mongo { using std::list; using std::map; + using std::ostream; using std::string; using std::stringstream; using std::vector; -namespace { - ShardRegistry staticShardInfo; + class StaticShardInfo { + public: + void reload() { + + vector<ShardType> shards; + Status status = grid.catalogManager()->getAllShards(&shards); + massert(13632, "couldn't get updated shard list from config server", status.isOK()); + + int numShards = shards.size(); + + LOG(1) << "found " << numShards << " shards listed on config server(s)"; + + boost::lock_guard<boost::mutex> lk( _mutex ); + + // We use the _lookup table for all shards and for the primary config DB. The config DB info, + // however, does not come from the ShardNS::shard. So when cleaning the _lookup table we leave + // the config state intact. The rationale is that this way we could drop shards that + // were removed without reinitializing the config DB information. + + ShardMap::iterator i = _lookup.find( "config" ); + if ( i != _lookup.end() ) { + ShardPtr config = i->second; + _lookup.clear(); + _lookup[ "config" ] = config; + } + else { + _lookup.clear(); + } + _rsLookup.clear(); + + for (const ShardType& shardData : shards) { + uassertStatusOK(shardData.validate()); + + ShardPtr shard = boost::make_shared<Shard>(shardData.getName(), + shardData.getHost(), + shardData.getMaxSize(), + shardData.getDraining()); + + _lookup[shardData.getName()] = shard; + _installHost(shardData.getHost(), shard); + } + + } + + ShardPtr findUsingLookUp(const string& shardName) { + ShardMap::iterator it; + { + boost::lock_guard<boost::mutex> lk(_mutex); + it = _lookup.find(shardName); + } + if (it != _lookup.end()) return it->second; + return ShardPtr(); + } + + ShardPtr findIfExists(const string& shardName) { + ShardPtr shard = findUsingLookUp(shardName); + if (shard) { + return shard; + } + // if we can't find the shard, we might just need to reload the cache + reload(); + return findUsingLookUp(shardName); + } + + ShardPtr find(const string& ident) { + string errmsg; + ConnectionString connStr = ConnectionString::parse(ident, errmsg); + + uassert(18642, str::stream() << "Error parsing connection string: " << ident, + errmsg.empty()); + + if (connStr.type() == ConnectionString::SET) { + boost::lock_guard<boost::mutex> lk(_rsMutex); + ShardMap::iterator iter = _rsLookup.find(connStr.getSetName()); + + if (iter == _rsLookup.end()) { + return ShardPtr(); + } + + return iter->second; + } + else { + boost::lock_guard<boost::mutex> lk(_mutex); + ShardMap::iterator iter = _lookup.find(ident); + + if (iter == _lookup.end()) { + return ShardPtr(); + } + + return iter->second; + } + } + + ShardPtr findWithRetry(const string& ident) { + ShardPtr shard(find(ident)); + + if (shard != NULL) { + return shard; + } + + // not in our maps, re-load all + reload(); + + shard = find(ident); + massert(13129 , str::stream() << "can't find shard for: " << ident, shard != NULL); + return shard; + } + + // Lookup shard by replica set name. Returns Shard::EMTPY if the name can't be found. + // Note: this doesn't refresh the table if the name isn't found, so it's possible that + // a newly added shard/Replica Set may not be found. + Shard lookupRSName( const string& name) { + boost::lock_guard<boost::mutex> lk( _rsMutex ); + ShardMap::iterator i = _rsLookup.find( name ); + + return (i == _rsLookup.end()) ? Shard::EMPTY : *(i->second.get()); + } + + // Useful for ensuring our shard data will not be modified while we use it + Shard findCopy( const string& ident ){ + ShardPtr found = findWithRetry(ident); + boost::lock_guard<boost::mutex> lk( _mutex ); + massert( 13128 , (string)"can't find shard for: " + ident , found.get() ); + return *found.get(); + } + + void set( const string& name , const Shard& s , bool setName = true , bool setAddr = true ) { + boost::lock_guard<boost::mutex> lk( _mutex ); + ShardPtr ss( new Shard( s ) ); + if ( setName ) + _lookup[name] = ss; + if ( setAddr ) + _installHost( s.getConnString() , ss ); + } + + void _installHost( const string& host , const ShardPtr& s ) { + _lookup[host] = s; + + const ConnectionString& cs = s->getAddress(); + if ( cs.type() == ConnectionString::SET ) { + if ( cs.getSetName().size() ) { + boost::lock_guard<boost::mutex> lk( _rsMutex); + _rsLookup[ cs.getSetName() ] = s; + } + vector<HostAndPort> servers = cs.getServers(); + for ( unsigned i=0; i<servers.size(); i++ ) { + _lookup[ servers[i].toString() ] = s; + } + } + } + + void remove( const string& name ) { + boost::lock_guard<boost::mutex> lk( _mutex ); + for ( ShardMap::iterator i = _lookup.begin(); i!=_lookup.end(); ) { + ShardPtr s = i->second; + if ( s->getName() == name ) { + _lookup.erase(i++); + } + else { + ++i; + } + } + for ( ShardMap::iterator i = _rsLookup.begin(); i!=_rsLookup.end(); ) { + ShardPtr s = i->second; + if ( s->getName() == name ) { + _rsLookup.erase(i++); + } + else { + ++i; + } + } + } + + void getAllShards( vector<ShardPtr>& all ) const { + boost::lock_guard<boost::mutex> lk( _mutex ); + std::set<string> seen; + for ( ShardMap::const_iterator i = _lookup.begin(); i!=_lookup.end(); ++i ) { + const ShardPtr& s = i->second; + if ( s->getName() == "config" ) + continue; + if ( seen.count( s->getName() ) ) + continue; + seen.insert( s->getName() ); + all.push_back( s ); + } + } + + void getAllShards( vector<Shard>& all ) const { + boost::lock_guard<boost::mutex> lk( _mutex ); + std::set<string> seen; + for ( ShardMap::const_iterator i = _lookup.begin(); i!=_lookup.end(); ++i ) { + const ShardPtr& s = i->second; + if ( s->getName() == "config" ) + continue; + if ( seen.count( s->getName() ) ) + continue; + seen.insert( s->getName() ); + all.push_back( *s ); + } + } + + + bool isAShardNode( const string& addr ) const { + boost::lock_guard<boost::mutex> lk( _mutex ); + + // check direct nods or set names + ShardMap::const_iterator i = _lookup.find( addr ); + if ( i != _lookup.end() ) + return true; + + // check for set nodes + for ( ShardMap::const_iterator i = _lookup.begin(); i!=_lookup.end(); ++i ) { + if ( i->first == "config" ) + continue; + + if ( i->second->containsNode( addr ) ) + return true; + } + + return false; + } + + bool getShardMap( BSONObjBuilder& result , string& errmsg ) const { + boost::lock_guard<boost::mutex> lk( _mutex ); + + BSONObjBuilder b( _lookup.size() + 50 ); + + for ( ShardMap::const_iterator i = _lookup.begin(); i!=_lookup.end(); ++i ) { + b.append( i->first , i->second->getConnString() ); + } + + result.append( "map" , b.obj() ); + + return true; + } + + private: + typedef map<string,ShardPtr> ShardMap; + ShardMap _lookup; // Map of both shardName -> Shard and hostName -> Shard + ShardMap _rsLookup; // Map from ReplSet name to shard + mutable mongo::mutex _mutex; + mutable mongo::mutex _rsMutex; + } staticShardInfo; class CmdGetShardMap : public Command { @@ -75,24 +319,16 @@ namespace { actions.addAction(ActionType::getShardMap); out->push_back(Privilege(ResourcePattern::forClusterResource(), actions)); } - virtual bool run(OperationContext* txn, const string&, mongo::BSONObj&, int, std::string& errmsg , mongo::BSONObjBuilder& result) { - - staticShardInfo.toBSON(&result); - - return true; + return staticShardInfo.getShardMap( result , errmsg ); } - } cmdGetShardMap; -} // namespace - - Shard::Shard() : _name(""), _addr(""), @@ -172,8 +408,12 @@ namespace { return staticShardInfo.lookupRSName(name); } - BSONObj Shard::runCommand(const std::string& db, const std::string& simple) const { - return runCommand(db, BSON(simple << 1)); + void Shard::printShardInfo( ostream& out ) { + vector<Shard> all; + staticShardInfo.getAllShards( all ); + for ( unsigned i=0; i<all.size(); i++ ) + out << all[i].toString() << "\n"; + out.flush(); } BSONObj Shard::runCommand( const string& db , const BSONObj& cmd ) const { @@ -188,11 +428,9 @@ namespace { return res; } - bool Shard::runCommand(const std::string& db, const std::string& simple, BSONObj& res) const { - return runCommand(db, BSON(simple << 1), res); - } - - bool Shard::runCommand(const string& db, const BSONObj& cmd, BSONObj& res) const { + bool Shard::runCommand(const string& db, + const BSONObj& cmd, + BSONObj& res) const { ScopedDbConnection conn(getConnString()); bool ok = conn->runCommand(db, cmd, res); conn.done(); @@ -277,7 +515,7 @@ namespace { } void Shard::installShard(const std::string& name, const Shard& shard) { - staticShardInfo.set(name, shard); + staticShardInfo.set(name, shard, true, false); } ShardStatus::ShardStatus(const Shard& shard, long long dataSizeBytes, const string& version): diff --git a/src/mongo/s/client/shard.h b/src/mongo/s/client/shard.h index 72df5387852..78e73a6ac36 100644 --- a/src/mongo/s/client/shard.h +++ b/src/mongo/s/client/shard.h @@ -30,7 +30,7 @@ #include <boost/shared_ptr.hpp> -#include "mongo/client/connection_string.h" +#include "mongo/client/dbclientinterface.h" namespace mongo { @@ -126,11 +126,25 @@ namespace mongo { bool ok() const { return _addr.size() > 0; } - BSONObj runCommand(const std::string& db, const std::string& simple) const; - BSONObj runCommand(const std::string& db, const BSONObj& cmd) const; + // Set internal to true to run the command with internal authentication privileges. + BSONObj runCommand( const std::string& db , const std::string& simple ) const { + return runCommand( db , BSON( simple << 1 ) ); + } + BSONObj runCommand( const std::string& db , const BSONObj& cmd ) const ; + + /** + * Runs a command on this shard. This method signature matches that of + * the connection on which this method relies upon. + */ + bool runCommand(const std::string& db, + const BSONObj& cmd, + BSONObj& res) const; - bool runCommand(const std::string& db, const std::string& simple, BSONObj& res) const; - bool runCommand(const std::string& db, const BSONObj& cmd, BSONObj& res) const; + bool runCommand(const std::string& db, + const std::string& simple, + BSONObj& res) const { + return runCommand(db, BSON(simple << 1), res); + } /** * Returns the version string from the shard based from the serverStatus command result. @@ -149,12 +163,13 @@ namespace mongo { /** * mostly for replica set - * retursn true if node is the shard + * retursn true if node is the shard * of if the replica set contains node */ bool containsNode( const std::string& node ) const; static void getAllShards( std::vector<Shard>& all ); + static void printShardInfo( std::ostream& out ); static Shard lookupRSName( const std::string& name); /** @@ -188,11 +203,17 @@ namespace mongo { class ShardStatus { public: + ShardStatus(const Shard& shard, long long dataSizeBytes, const std::string& version); + friend std::ostream& operator << (std::ostream& out, const ShardStatus& s) { + out << s.toString(); + return out; + } + std::string toString() const { std::stringstream ss; - ss << "shard: " << _shard.toString() + ss << "shard: " << _shard << " dataSizeBytes: " << _dataSizeBytes << " version: " << _mongoVersion; return ss.str(); diff --git a/src/mongo/s/client/shard_registry.cpp b/src/mongo/s/client/shard_registry.cpp deleted file mode 100644 index 31a34039345..00000000000 --- a/src/mongo/s/client/shard_registry.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/** - * Copyright (C) 2015 MongoDB 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/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kSharding - -#include "mongo/platform/basic.h" - -#include "mongo/s/client/shard_registry.h" - -#include <boost/make_shared.hpp> -#include <boost/thread/lock_guard.hpp> - -#include "mongo/client/connection_string.h" -#include "mongo/s/catalog/catalog_manager.h" -#include "mongo/s/catalog/type_shard.h" -#include "mongo/s/client/shard.h" -#include "mongo/s/grid.h" -#include "mongo/util/log.h" -#include "mongo/util/mongoutils/str.h" - -namespace mongo { - - using boost::shared_ptr; - using std::string; - using std::vector; - - - ShardRegistry::ShardRegistry() = default; - - ShardRegistry::~ShardRegistry() = default; - - void ShardRegistry::reload() { - vector<ShardType> shards; - Status status = grid.catalogManager()->getAllShards(&shards); - massert(13632, "couldn't get updated shard list from config server", status.isOK()); - - int numShards = shards.size(); - - LOG(1) << "found " << numShards << " shards listed on config server(s)"; - - boost::lock_guard<boost::mutex> lk(_mutex); - - // We use the _lookup table for all shards and for the primary config DB. The config DB - // info, however, does not come from the ShardNS::shard. So when cleaning the _lookup table - // we leave the config state intact. The rationale is that this way we could drop shards - // that were removed without reinitializing the config DB information. - - ShardMap::iterator i = _lookup.find("config"); - if (i != _lookup.end()) { - shared_ptr<Shard> config = i->second; - _lookup.clear(); - _lookup["config"] = config; - } - else { - _lookup.clear(); - } - _rsLookup.clear(); - - for (const ShardType& shardData : shards) { - uassertStatusOK(shardData.validate()); - - shared_ptr<Shard> shard = boost::make_shared<Shard>(shardData.getName(), - shardData.getHost(), - shardData.getMaxSize(), - shardData.getDraining()); - _lookup[shardData.getName()] = shard; - _installHost(shardData.getHost(), shard); - } - } - - shared_ptr<Shard> ShardRegistry::findIfExists(const string& shardName) { - shared_ptr<Shard> shard = _findUsingLookUp(shardName); - if (shard) { - return shard; - } - - // If we can't find the shard, we might just need to reload the cache - reload(); - - return _findUsingLookUp(shardName); - } - - shared_ptr<Shard> ShardRegistry::find(const string& ident) { - string errmsg; - ConnectionString connStr = ConnectionString::parse(ident, errmsg); - uassert(18642, - str::stream() << "Error parsing connection string: " << ident, - errmsg.empty()); - - if (connStr.type() == ConnectionString::SET) { - boost::lock_guard<boost::mutex> lk(_rsMutex); - ShardMap::iterator iter = _rsLookup.find(connStr.getSetName()); - - if (iter == _rsLookup.end()) { - return boost::make_shared<Shard>(); - } - - return iter->second; - } - else { - boost::lock_guard<boost::mutex> lk(_mutex); - ShardMap::iterator iter = _lookup.find(ident); - - if (iter == _lookup.end()) { - return boost::make_shared<Shard>(); - } - - return iter->second; - } - } - - Shard ShardRegistry::lookupRSName(const string& name) { - boost::lock_guard<boost::mutex> lk(_rsMutex); - ShardMap::iterator i = _rsLookup.find(name); - - return (i == _rsLookup.end()) ? Shard::EMPTY : *(i->second.get()); - } - - Shard ShardRegistry::findCopy(const string& ident){ - shared_ptr<Shard> found = _findWithRetry(ident); - - boost::lock_guard<boost::mutex> lk(_mutex); - massert(13128, str::stream() << "can't find shard for: " << ident, found.get()); - - return *found.get(); - } - - void ShardRegistry::set(const string& name, const Shard& s) { - shared_ptr<Shard> ss(boost::make_shared<Shard>(s)); - - boost::lock_guard<boost::mutex> lk(_mutex); - _lookup[name] = ss; - } - - void ShardRegistry::remove(const string& name) { - boost::lock_guard<boost::mutex> lk(_mutex); - - for (ShardMap::iterator i = _lookup.begin(); i != _lookup.end();) { - shared_ptr<Shard> s = i->second; - if (s->getName() == name) { - _lookup.erase(i++); - } - else { - ++i; - } - } - - for (ShardMap::iterator i = _rsLookup.begin(); i != _rsLookup.end();) { - shared_ptr<Shard> s = i->second; - if (s->getName() == name) { - _rsLookup.erase(i++); - } - else { - ++i; - } - } - } - - void ShardRegistry::getAllShards(vector<Shard>& all) const { - std::set<string> seen; - - boost::lock_guard<boost::mutex> lk(_mutex); - for (ShardMap::const_iterator i = _lookup.begin(); i != _lookup.end(); ++i) { - const shared_ptr<Shard>& s = i->second; - if (s->getName() == "config") { - continue; - } - - if (seen.count(s->getName())) { - continue; - } - - seen.insert(s->getName()); - all.push_back(*s); - } - } - - - bool ShardRegistry::isAShardNode(const string& addr) const { - boost::lock_guard<boost::mutex> lk(_mutex); - - // Check direct nods or set names - ShardMap::const_iterator i = _lookup.find(addr); - if (i != _lookup.end()) { - return true; - } - - // Check for set nodes - for (ShardMap::const_iterator i = _lookup.begin(); i != _lookup.end(); ++i) { - if (i->first == "config") { - continue; - } - - if (i->second->containsNode(addr)) { - return true; - } - } - - return false; - } - - void ShardRegistry::toBSON(BSONObjBuilder* result) const { - BSONObjBuilder b(_lookup.size() + 50); - - boost::lock_guard<boost::mutex> lk(_mutex); - - for (ShardMap::const_iterator i = _lookup.begin(); i != _lookup.end(); ++i) { - b.append(i->first, i->second->getConnString()); - } - - result->append("map", b.obj()); - } - - shared_ptr<Shard> ShardRegistry::_findWithRetry(const string& ident) { - shared_ptr<Shard> shard(find(ident)); - if (shard != NULL) { - return shard; - } - - // Not in our maps, re-load all - reload(); - - shard = find(ident); - massert(13129, str::stream() << "can't find shard for: " << ident, shard != NULL); - - return shard; - } - - - shared_ptr<Shard> ShardRegistry::_findUsingLookUp(const string& shardName) { - boost::lock_guard<boost::mutex> lk(_mutex); - ShardMap::iterator it = _lookup.find(shardName); - - if (it != _lookup.end()) { - return it->second; - } - - return boost::make_shared<Shard>(); - } - - void ShardRegistry::_installHost(const string& host, const shared_ptr<Shard>& s) { - _lookup[host] = s; - - const ConnectionString& cs = s->getAddress(); - - if (cs.type() == ConnectionString::SET) { - if (cs.getSetName().size()) { - boost::lock_guard<boost::mutex> lk(_rsMutex); - _rsLookup[cs.getSetName()] = s; - } - - vector<HostAndPort> servers = cs.getServers(); - for (unsigned i = 0; i < servers.size(); i++) { - _lookup[servers[i].toString()] = s; - } - } - } - -} // namespace mongo diff --git a/src/mongo/s/client/shard_registry.h b/src/mongo/s/client/shard_registry.h deleted file mode 100644 index b888d55e723..00000000000 --- a/src/mongo/s/client/shard_registry.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Copyright (C) 2015 MongoDB 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/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <boost/shared_ptr.hpp> -#include <boost/thread/mutex.hpp> -#include <string> -#include <vector> - -namespace mongo { - - class BSONObjBuilder; - class Shard; - - - /** - * Maintains the set of all shards known to the MongoS instance. - */ - class ShardRegistry { - public: - ShardRegistry(); - ~ShardRegistry(); - - void reload(); - - boost::shared_ptr<Shard> findIfExists(const std::string& shardName); - boost::shared_ptr<Shard> find(const std::string& ident); - - /** - * Lookup shard by replica set name. Returns Shard::EMTPY if the name can't be found. - * Note: this doesn't refresh the table if the name isn't found, so it's possible that a - * newly added shard/Replica Set may not be found. - */ - Shard lookupRSName(const std::string& name); - - /** - * Useful for ensuring our shard data will not be modified while we use it. - */ - Shard findCopy(const std::string& ident); - - void set(const std::string& name, const Shard& s); - - void remove(const std::string& name); - - void getAllShards(std::vector<Shard>& all) const; - - bool isAShardNode(const std::string& addr) const; - - void toBSON(BSONObjBuilder* result) const; - - - private: - typedef std::map<std::string, boost::shared_ptr<Shard>> ShardMap; - - - boost::shared_ptr<Shard> _findWithRetry(const std::string& ident); - - boost::shared_ptr<Shard> _findUsingLookUp(const std::string& shardName); - - void _installHost(const std::string& host, const boost::shared_ptr<Shard>& s); - - - // Map of both shardName -> Shard and hostName -> Shard - mutable boost::mutex _mutex; - ShardMap _lookup; - - // Map from ReplSet name to shard - mutable boost::mutex _rsMutex; - ShardMap _rsLookup; - }; - -} // namespace mongo diff --git a/src/mongo/s/config.cpp b/src/mongo/s/config.cpp index a7fde93c451..4e419bf39e6 100644 --- a/src/mongo/s/config.cpp +++ b/src/mongo/s/config.cpp @@ -180,6 +180,18 @@ namespace mongo { return i->second.isSharded(); } + ShardPtr DBConfig::getShardIfExists( const string& ns ){ + try{ + // TODO: this function assumes the _primary will not change under-the-covers, but so does + // getShard() in general + return ShardPtr( new Shard( getShard( ns ) ) ); + } + catch( AssertionException& e ){ + warning() << "primary not found for " << ns << causedBy( e ) << endl; + return ShardPtr(); + } + } + const Shard& DBConfig::getShard( const string& ns ) { if ( isSharded( ns ) ) return Shard::EMPTY; @@ -228,9 +240,7 @@ namespace mongo { } // Handles weird logic related to getting *either* a chunk manager *or* the collection primary shard - void DBConfig::getChunkManagerOrPrimary(const string& ns, - boost::shared_ptr<ChunkManager>& manager, - boost::shared_ptr<Shard>& primary) { + void DBConfig::getChunkManagerOrPrimary( const string& ns, ChunkManagerPtr& manager, ShardPtr& primary ){ // The logic here is basically that at any time, our collection can become sharded or unsharded // via a command. If we're not sharded, we want to send data to the primary, if sharded, we want diff --git a/src/mongo/s/config.h b/src/mongo/s/config.h index 3be7bc1bba7..1bbb1d2dd41 100644 --- a/src/mongo/s/config.h +++ b/src/mongo/s/config.h @@ -125,14 +125,17 @@ namespace mongo { // Atomically returns *either* the chunk manager *or* the primary shard for the collection, // neither if the collection doesn't exist. - void getChunkManagerOrPrimary(const std::string& ns, - boost::shared_ptr<ChunkManager>& manager, - boost::shared_ptr<Shard>& primary); + void getChunkManagerOrPrimary(const std::string& ns, boost::shared_ptr<ChunkManager>& manager, ShardPtr& primary); boost::shared_ptr<ChunkManager> getChunkManager(const std::string& ns, bool reload = false, bool forceReload = false); boost::shared_ptr<ChunkManager> getChunkManagerIfExists(const std::string& ns, bool reload = false, bool forceReload = false); const Shard& getShard( const std::string& ns ); + /** + * @return the correct for shard for the ns + * if the namespace is sharded, will return NULL + */ + ShardPtr getShardIfExists( const std::string& ns ); void setPrimary( const std::string& s ); |