diff options
author | Antonin Kral <a.kral@bobek.cz> | 2010-03-25 19:21:32 +0100 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2010-03-25 19:21:32 +0100 |
commit | 0ca01a91ae0a3562e54c226e7b9512feb2ea83d0 (patch) | |
tree | 2b3886e435b0217d6afd63a213b04d32bb4b4f6f /s | |
parent | a696359b248adef0cc8576fce3f473535e995136 (diff) | |
download | mongodb-0ca01a91ae0a3562e54c226e7b9512feb2ea83d0.tar.gz |
Imported Upstream version 1.4.0
Diffstat (limited to 's')
-rw-r--r-- | s/chunk.cpp | 45 | ||||
-rw-r--r-- | s/chunk.h | 40 | ||||
-rw-r--r-- | s/commands_admin.cpp | 10 | ||||
-rw-r--r-- | s/commands_public.cpp | 158 | ||||
-rw-r--r-- | s/config.cpp | 49 | ||||
-rw-r--r-- | s/config.h | 4 | ||||
-rw-r--r-- | s/cursors.cpp | 16 | ||||
-rw-r--r-- | s/cursors.h | 16 | ||||
-rw-r--r-- | s/d_logic.cpp | 11 | ||||
-rw-r--r-- | s/d_logic.h | 16 | ||||
-rw-r--r-- | s/dbgrid.vcproj | 44 | ||||
-rw-r--r-- | s/request.cpp | 8 | ||||
-rw-r--r-- | s/request.h | 18 | ||||
-rw-r--r-- | s/s_only.cpp | 4 | ||||
-rw-r--r-- | s/server.cpp | 132 | ||||
-rw-r--r-- | s/strategy.cpp | 24 | ||||
-rw-r--r-- | s/strategy.h | 16 | ||||
-rw-r--r-- | s/strategy_shard.cpp | 16 | ||||
-rw-r--r-- | s/strategy_single.cpp | 16 | ||||
-rw-r--r-- | s/util.h | 1 |
20 files changed, 518 insertions, 126 deletions
diff --git a/s/chunk.cpp b/s/chunk.cpp index 47c13e8..73d17d9 100644 --- a/s/chunk.cpp +++ b/s/chunk.cpp @@ -28,7 +28,7 @@ namespace mongo { // ------- Shard -------- - long Chunk::MaxChunkSize = 1024 * 1204 * 50; + int Chunk::MaxChunkSize = 1024 * 1204 * 200; Chunk::Chunk( ChunkManager * manager ) : _manager( manager ){ _modified = false; @@ -41,13 +41,13 @@ namespace mongo { _markModified(); } - bool Chunk::contains( const BSONObj& obj ){ + bool Chunk::contains( const BSONObj& obj ) const{ return _manager->getShardKey().compare( getMin() , obj ) <= 0 && _manager->getShardKey().compare( obj , getMax() ) < 0; } - BSONObj Chunk::pickSplitPoint(){ + BSONObj Chunk::pickSplitPoint() const{ int sort = 0; if ( _manager->getShardKey().globalMin().woCompare( getMin() ) == 0 ){ @@ -77,7 +77,7 @@ namespace mongo { } BSONObj end = conn->findOne( _ns , q ); conn.done(); - + if ( ! end.isEmpty() ) return _manager->getShardKey().extractKey( end ); } @@ -93,9 +93,25 @@ namespace mongo { ss << "medianKey command failed: " << result; uassert( 10164 , ss.str() , 0 ); } + + BSONObj median = result.getObjectField( "median" ); + if (median == getMin()){ + //TODO compound support + BSONElement key = getMin().firstElement(); + BSONObjBuilder b; + b.appendAs("$gt", key); + + Query q = QUERY(key.fieldName() << b.obj()); + q.sort(_manager->getShardKey().key()); + + median = conn->findOne(_ns, q); + median = _manager->getShardKey().extractKey( median ); + PRINT(median); + } + conn.done(); - return result.getObjectField( "median" ).getOwned(); + return median.getOwned(); } Chunk * Chunk::split(){ @@ -109,6 +125,8 @@ namespace mongo { << "\t self : " << toString() << endl; uassert( 10166 , "locking namespace on server failed" , lockNamespaceOnServer( getShard() , _ns ) ); + uassert( 13003 , "can't split chunk. does it have only one distinct value?" , + !m.isEmpty() && _min.woCompare(m) && _max.woCompare(m)); Chunk * s = new Chunk( _manager ); s->_ns = _ns; @@ -216,10 +234,13 @@ namespace mongo { if ( _dataWritten < MaxChunkSize / 5 ) return false; + + log(1) << "\t want to split chunk : " << this << endl; _dataWritten = 0; - if ( _min.woCompare( _max ) == 0 ){ + BSONObj split_point = pickSplitPoint(); + if ( split_point.isEmpty() || _min == split_point || _max == split_point) { log() << "SHARD PROBLEM** shard is too big, but can't split: " << toString() << endl; return false; } @@ -229,7 +250,7 @@ namespace mongo { return false; log() << "autosplitting " << _ns << " size: " << size << " shard: " << toString() << endl; - Chunk * newShard = split(); + Chunk * newShard = split(split_point); moveIfShould( newShard ); @@ -268,7 +289,7 @@ namespace mongo { return true; } - long Chunk::getPhysicalSize(){ + long Chunk::getPhysicalSize() const{ ScopedDbConnection conn( getShard() ); BSONObj result; @@ -283,7 +304,7 @@ namespace mongo { } - long Chunk::countObjects( const BSONObj& filter ){ + long Chunk::countObjects( const BSONObj& filter ) const{ ScopedDbConnection conn( getShard() ); BSONObj f = getFilter(); @@ -297,14 +318,14 @@ namespace mongo { return (long)n; } - bool Chunk::operator==( const Chunk& s ){ + bool Chunk::operator==( const Chunk& s ) const{ return _manager->getShardKey().compare( _min , s._min ) == 0 && _manager->getShardKey().compare( _max , s._max ) == 0 ; } - void Chunk::getFilter( BSONObjBuilder& b ){ + void Chunk::getFilter( BSONObjBuilder& b ) const{ _manager->_key.getFilter( b , _min , _max ); } @@ -383,7 +404,7 @@ namespace mongo { } - ShardKeyPattern Chunk::skey(){ + ShardKeyPattern Chunk::skey() const{ return _manager->getShardKey(); } @@ -61,27 +61,27 @@ namespace mongo { _max = o; } - string getShard(){ + string getShard() const{ return _shard; } void setShard( string shard ); - bool contains( const BSONObj& obj ); + bool contains( const BSONObj& obj ) const; string toString() const; operator string() const { return toString(); } - bool operator==(const Chunk& s); + bool operator==(const Chunk& s) const; - bool operator!=(const Chunk& s){ + bool operator!=(const Chunk& s) const{ return ! ( *this == s ); } - void getFilter( BSONObjBuilder& b ); - BSONObj getFilter(){ BSONObjBuilder b; getFilter( b ); return b.obj(); } + void getFilter( BSONObjBuilder& b ) const; + BSONObj getFilter() const{ BSONObjBuilder b; getFilter( b ); return b.obj(); } - BSONObj pickSplitPoint(); + BSONObj pickSplitPoint() const; Chunk * split(); Chunk * split( const BSONObj& middle ); @@ -89,9 +89,9 @@ namespace mongo { * @return size of shard in bytes * talks to mongod to do this */ - long getPhysicalSize(); + long getPhysicalSize() const; - long countObjects( const BSONObj& filter = BSONObj() ); + long countObjects( const BSONObj& filter = BSONObj() ) const; /** * if the amount of data written nears the max size of a shard @@ -119,14 +119,14 @@ namespace mongo { void _markModified(); - static long MaxChunkSize; + static int MaxChunkSize; private: // main shard info ChunkManager * _manager; - ShardKeyPattern skey(); + ShardKeyPattern skey() const; string _ns; BSONObj _min; @@ -218,4 +218,22 @@ namespace mongo { static unsigned long long NextSequenceNumber; }; + // like BSONObjCmp. for use as an STL comparison functor + // key-order in "order" argument must match key-order in shardkey + class ChunkCmp { + public: + ChunkCmp( const BSONObj &order = BSONObj() ) : _cmp( order ) {} + bool operator()( const Chunk &l, const Chunk &r ) const { + return _cmp(l.getMin(), r.getMin()); + } + + bool operator()( const Chunk *l, const Chunk *r ) const { + return operator()(*l, *r); + } + private: + BSONObjCmp _cmp; + }; + + + } // namespace mongo diff --git a/s/commands_admin.cpp b/s/commands_admin.cpp index e79b529..0b2baa0 100644 --- a/s/commands_admin.cpp +++ b/s/commands_admin.cpp @@ -54,6 +54,9 @@ namespace mongo { virtual bool adminOnly() { return true; } + + // all grid commands are designed not to lock + virtual LockType locktype(){ return NONE; } }; // --------------- misc commands ---------------------- @@ -506,8 +509,7 @@ namespace mongo { if ( host == "localhost" || host.find( "localhost:" ) == 0 || host == "127.0.0.1" || host.find( "127.0.0.1:" ) == 0 ){ - if ( cmdObj["allowLocal"].type() != Bool || - ! cmdObj["allowLocal"].boolean() ){ + if ( ! cmdObj["allowLocal"].trueValue() ){ errmsg = "can't use localhost as a shard since all shards need to communicate. " "allowLocal to override for testing"; @@ -586,6 +588,7 @@ namespace mongo { class IsDbGridCmd : public Command { public: + virtual LockType locktype(){ return NONE; } virtual bool slaveOk() { return true; } @@ -599,6 +602,7 @@ namespace mongo { class CmdIsMaster : public Command { public: + virtual LockType locktype(){ return NONE; } virtual bool requiresAuth() { return false; } virtual bool slaveOk() { return true; @@ -616,6 +620,7 @@ namespace mongo { class CmdShardingGetPrevError : public Command { public: + virtual LockType locktype(){ return NONE; } virtual bool requiresAuth() { return false; } virtual bool slaveOk() { return true; @@ -632,6 +637,7 @@ namespace mongo { class CmdShardingGetLastError : public Command { public: + virtual LockType locktype(){ return NONE; } virtual bool requiresAuth() { return false; } virtual bool slaveOk() { return true; diff --git a/s/commands_public.cpp b/s/commands_public.cpp index 2d3de7a..649d7d1 100644 --- a/s/commands_public.cpp +++ b/s/commands_public.cpp @@ -42,6 +42,10 @@ namespace mongo { virtual bool adminOnly() { return false; } + + // all grid commands are designed not to lock + virtual LockType locktype(){ return NONE; } + protected: string getDBName( string ns ){ return ns.substr( 0 , ns.size() - 5 ); @@ -173,6 +177,160 @@ namespace mongo { } } countCmd; + class CollectionStats : public PublicGridCommand { + public: + CollectionStats() : PublicGridCommand("collstats") { } + bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool){ + string dbName = getDBName( ns ); + string collection = cmdObj.firstElement().valuestrsafe(); + string fullns = dbName + "." + collection; + + DBConfig * conf = grid.getDBConfig( dbName , false ); + + if ( ! conf || ! conf->isShardingEnabled() || ! conf->isSharded( fullns ) ){ + result.appendBool("sharded", false); + return passthrough( conf , cmdObj , result); + } + result.appendBool("sharded", true); + + ChunkManager * cm = conf->getChunkManager( fullns ); + massert( 12594 , "how could chunk manager be null!" , cm ); + + set<string> servers; + cm->getAllServers(servers); + + BSONObjBuilder shardStats; + long long count=0; + long long size=0; + long long storageSize=0; + int nindexes=0; + for ( set<string>::iterator i=servers.begin(); i!=servers.end(); i++ ){ + ScopedDbConnection conn( *i ); + BSONObj res; + if ( ! conn->runCommand( dbName , cmdObj , res ) ){ + errmsg = "failed on shard: " + res.toString(); + return false; + } + conn.done(); + + count += res["count"].numberLong(); + size += res["size"].numberLong(); + storageSize += res["storageSize"].numberLong(); + + if (nindexes) + massert(12595, "nindexes should be the same on all shards!", nindexes == res["nindexes"].numberInt()); + else + nindexes = res["nindexes"].numberInt(); + + shardStats.append(*i, res); + } + + result.append("ns", fullns); + result.appendNumber("count", count); + result.appendNumber("size", size); + result.appendNumber("storageSize", storageSize); + result.append("nindexes", nindexes); + + result.append("nchunks", cm->numChunks()); + result.append("shards", shardStats.obj()); + + return true; + } + } collectionStatsCmd; + + class FindAndModifyCmd : public PublicGridCommand { + public: + FindAndModifyCmd() : PublicGridCommand("findandmodify") { } + bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool){ + string dbName = getDBName( ns ); + string collection = cmdObj.firstElement().valuestrsafe(); + string fullns = dbName + "." + collection; + + BSONObj filter = cmdObj.getObjectField("query"); + + DBConfig * conf = grid.getDBConfig( dbName , false ); + + if ( ! conf || ! conf->isShardingEnabled() || ! conf->isSharded( fullns ) ){ + return passthrough( conf , cmdObj , result); + } + + ChunkManager * cm = conf->getChunkManager( fullns ); + massert( 13002 , "how could chunk manager be null!" , cm ); + + vector<Chunk*> chunks; + cm->getChunksForQuery( chunks , filter ); + + BSONObj sort = cmdObj.getObjectField("sort"); + if (!sort.isEmpty()){ + ShardKeyPattern& sk = cm->getShardKey(); + { + BSONObjIterator k (sk.key()); + BSONObjIterator s (sort); + bool good = true; + while (k.more()){ + if (!s.more()){ + good = false; + break; + } + + BSONElement ke = k.next(); + BSONElement se = s.next(); + + // TODO consider values when we support compound keys + if (strcmp(ke.fieldName(), se.fieldName()) != 0){ + good = false; + break; + } + } + + uassert(13001, "Sort must match shard key for sharded findandmodify", good); + } + + std::sort(chunks.begin(), chunks.end(), ChunkCmp(sort)); + } + + for ( vector<Chunk*>::iterator i = chunks.begin() ; i != chunks.end() ; i++ ){ + Chunk * c = *i; + + ScopedDbConnection conn( c->getShard() ); + BSONObj res; + bool ok = conn->runCommand( conf->getName() , fixCmdObj(cmdObj, c) , res ); + conn.done(); + + if (ok || (strcmp(res["errmsg"].valuestrsafe(), "No matching object found") != 0)){ + result.appendElements(res); + return ok; + } + } + + return true; + } + + private: + BSONObj fixCmdObj(const BSONObj& cmdObj, const Chunk* chunk){ + assert(chunk); + + BSONObjBuilder b; + BSONObjIterator i(cmdObj); + bool foundQuery = false; + while (i.more()){ + BSONElement e = i.next(); + if (strcmp(e.fieldName(), "query") != 0){ + b.append(e); + }else{ + foundQuery = true; + b.append("query", ClusteredCursor::concatQuery(e.embeddedObjectUserCheck(), chunk->getFilter())); + } + } + + if (!foundQuery) + b.append("query", chunk->getFilter()); + + return b.obj(); + } + + } findAndModifyCmd; + class ConvertToCappedCmd : public NotAllowedOnShardedCollectionCmd { public: ConvertToCappedCmd() : NotAllowedOnShardedCollectionCmd("convertToCapped"){} diff --git a/s/config.cpp b/s/config.cpp index 0bfb5a3..c3c3668 100644 --- a/s/config.cpp +++ b/s/config.cpp @@ -129,6 +129,8 @@ namespace mongo { void DBConfig::unserialize(const BSONObj& from){ _name = from.getStringField("name"); + log(1) << "DBConfig unserialize: " << _name << " " << from << endl; + _shardingEnabled = from.getBoolField("partitioned"); _primary = from.getStringField("primary"); @@ -297,7 +299,7 @@ namespace mongo { if ( database == "config" ) return &configServer; - boostlock l( _lock ); + scoped_lock l( _lock ); DBConfig*& cc = _databases[database]; if ( cc == 0 ){ @@ -333,7 +335,7 @@ namespace mongo { void Grid::removeDB( string database ){ uassert( 10186 , "removeDB expects db name" , database.find( '.' ) == string::npos ); - boostlock l( _lock ); + scoped_lock l( _lock ); _databases.erase( database ); } @@ -369,30 +371,35 @@ namespace mongo { } ourHostname = hn; + stringstream fullString; + set<string> hosts; for ( size_t i=0; i<configHosts.size(); i++ ){ string host = configHosts[i]; hosts.insert( getHost( host , false ) ); configHosts[i] = getHost( host , true ); + if ( i > 0 ) + fullString << ","; + fullString << configHosts[i]; } - + for ( set<string>::iterator i=hosts.begin(); i!=hosts.end(); i++ ){ string host = *i; bool ok = false; - for ( int x=0; x<10; x++ ){ + for ( int x=10; x>0; x-- ){ if ( ! hostbyname( host.c_str() ).empty() ){ ok = true; break; } - log() << "can't resolve DNS for [" << host << "] sleeping and trying " << (10-x) << " more times" << endl; + log() << "can't resolve DNS for [" << host << "] sleeping and trying " << x << " more times" << endl; sleepsecs( 10 ); } if ( ! ok ) return false; } - uassert( 10188 , "can only hand 1 config db right now" , configHosts.size() == 1 ); - _primary = configHosts[0]; + _primary = fullString.str(); + log(1) << " config string : " << fullString.str() << endl; return true; } @@ -448,7 +455,7 @@ namespace mongo { if ( cur == 0 ){ ScopedDbConnection conn( _primary ); - conn->insert( "config.version" , BSON( "version" << VERSION ) ); + conn->insert( "config.version" , BSON( "_id" << 1 << "version" << VERSION ) ); pool.flush(); assert( VERSION == dbConfigVersion( conn.conn() ) ); conn.done(); @@ -459,6 +466,32 @@ namespace mongo { return -8; } + void ConfigServer::reloadSettings(){ + set<string> got; + + ScopedDbConnection conn( _primary ); + auto_ptr<DBClientCursor> c = conn->query( "config.settings" , BSONObj() ); + while ( c->more() ){ + BSONObj o = c->next(); + string name = o["_id"].valuestrsafe(); + got.insert( name ); + if ( name == "chunksize" ){ + log(1) << "MaxChunkSize: " << o["value"] << endl; + Chunk::MaxChunkSize = o["value"].numberInt() * 1024 * 1024; + } + else { + log() << "warning: unknown setting [" << name << "]" << endl; + } + } + + if ( ! got.count( "chunksize" ) ){ + conn->insert( "config.settings" , BSON( "_id" << "chunksize" << + "value" << (Chunk::MaxChunkSize / ( 1024 * 1024 ) ) ) ); + } + + conn.done(); + } + string ConfigServer::getHost( string name , bool withPort ){ if ( name.find( ":" ) ){ if ( withPort ) @@ -151,7 +151,7 @@ namespace mongo { unsigned long long getNextOpTime() const; private: map<string,DBConfig*> _databases; - boost::mutex _lock; // TODO: change to r/w lock + mongo::mutex _lock; // TODO: change to r/w lock }; class ConfigServer : public DBConfig { @@ -180,6 +180,8 @@ namespace mongo { int dbConfigVersion(); int dbConfigVersion( DBClientBase& conn ); + + void reloadSettings(); /** * @return 0 = ok, otherwise error # diff --git a/s/cursors.cpp b/s/cursors.cpp index 23b8eaf..a1c9dfa 100644 --- a/s/cursors.cpp +++ b/s/cursors.cpp @@ -1,4 +1,20 @@ // cursors.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 "stdafx.h" #include "cursors.h" diff --git a/s/cursors.h b/s/cursors.h index b1ed4b0..a61bed3 100644 --- a/s/cursors.h +++ b/s/cursors.h @@ -1,4 +1,20 @@ // cursors.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 diff --git a/s/d_logic.cpp b/s/d_logic.cpp index cc627eb..2a9cde3 100644 --- a/s/d_logic.cpp +++ b/s/d_logic.cpp @@ -79,6 +79,7 @@ namespace mongo { class WriteBackCommand : public MongodShardCommand { public: + virtual LockType locktype(){ return NONE; } WriteBackCommand() : MongodShardCommand( "writebacklisten" ){} bool run(const char *cmdns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool){ @@ -90,8 +91,6 @@ namespace mongo { const OID id = e.__oid(); - dbtemprelease unlock; - if ( ! clientQueues[id.str()] ) clientQueues[id.str()] = new BlockingQueue<BSONObj>(); @@ -114,6 +113,8 @@ namespace mongo { help << " example: { setShardVersion : 'alleyinsider.foo' , version : 1 , configdb : '' } "; } + virtual LockType locktype(){ return WRITE; } // TODO: figure out how to make this not need to lock + bool run(const char *cmdns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool){ bool authoritative = cmdObj.getBoolField( "authoritative" ); @@ -247,6 +248,8 @@ namespace mongo { help << " example: { getShardVersion : 'alleyinsider.foo' } "; } + virtual LockType locktype(){ return WRITE; } // TODO: figure out how to make this not need to lock + bool run(const char *cmdns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool){ string ns = cmdObj["getShardVersion"].valuestrsafe(); if ( ns.size() == 0 ){ @@ -273,6 +276,8 @@ namespace mongo { virtual void help( stringstream& help ) const { help << "should not be calling this directly" << endl; } + + virtual LockType locktype(){ return WRITE; } bool run(const char *cmdns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool){ // so i have to start clone, tell caller its ok to make change @@ -342,6 +347,8 @@ namespace mongo { virtual void help( stringstream& help ) const { help << "should not be calling this directly" << endl; } + + virtual LockType locktype(){ return WRITE; } bool run(const char *cmdns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool){ // see MoveShardStartCommand::run diff --git a/s/d_logic.h b/s/d_logic.h index 3e483c4..e426cb2 100644 --- a/s/d_logic.h +++ b/s/d_logic.h @@ -1,4 +1,20 @@ // d_logic.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 diff --git a/s/dbgrid.vcproj b/s/dbgrid.vcproj index 2c8ef85..06e6c32 100644 --- a/s/dbgrid.vcproj +++ b/s/dbgrid.vcproj @@ -42,7 +42,7 @@ Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""..\pcre-7.4";"C:\Program Files\boost\boost_1_35_0""
- PreprocessorDefinitions="USE_ASIO;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;HAVE_CONFIG_H;PCRE_STATIC"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;HAVE_CONFIG_H;PCRE_STATIC"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -433,6 +433,10 @@ >
</File>
<File
+ RelativePath="..\db\cmdline.cpp"
+ >
+ </File>
+ <File
RelativePath="..\db\commands.cpp"
>
</File>
@@ -497,40 +501,8 @@ >
</File>
<File
- RelativePath="..\util\message_server_asio.cpp"
+ RelativePath="..\util\message_server_port.cpp"
>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="0"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="0"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="release_nojni|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="0"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug Recstore|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="0"
- />
- </FileConfiguration>
</File>
<File
RelativePath="..\db\nonce.cpp"
@@ -545,6 +517,10 @@ >
</File>
<File
+ RelativePath="..\client\syncclusterconnection.cpp"
+ >
+ </File>
+ <File
RelativePath="..\util\thread_pool.cpp"
>
</File>
diff --git a/s/request.cpp b/s/request.cpp index 8bebd64..02ada3c 100644 --- a/s/request.cpp +++ b/s/request.cpp @@ -74,7 +74,7 @@ namespace mongo { void Request::process( int attempt ){ - log(2) << "Request::process ns: " << getns() << " msg id:" << (int)(_m.data->id) << " attempt: " << attempt << endl; + log(3) << "Request::process ns: " << getns() << " msg id:" << (int)(_m.data->id) << " attempt: " << attempt << endl; int op = _m.data->operation(); assert( op > dbMsg ); @@ -118,7 +118,7 @@ namespace mongo { } ClientInfo::~ClientInfo(){ - boostlock lk( _clientsLock ); + scoped_lock lk( _clientsLock ); ClientCache::iterator i = _clients.find( _id ); if ( i != _clients.end() ){ _clients.erase( i ); @@ -157,7 +157,7 @@ namespace mongo { return info; } - boostlock lk( _clientsLock ); + scoped_lock lk( _clientsLock ); ClientCache::iterator i = _clients.find( clientId ); if ( i != _clients.end() ) return i->second; @@ -169,7 +169,7 @@ namespace mongo { } map<int,ClientInfo*> ClientInfo::_clients; - boost::mutex ClientInfo::_clientsLock; + mongo::mutex ClientInfo::_clientsLock; boost::thread_specific_ptr<ClientInfo> ClientInfo::_tlInfo; } // namespace mongo diff --git a/s/request.h b/s/request.h index 689216c..2c02724 100644 --- a/s/request.h +++ b/s/request.h @@ -1,4 +1,20 @@ // request.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 @@ -111,7 +127,7 @@ namespace mongo { set<string> * _prev; int _lastAccess; - static boost::mutex _clientsLock; + static mongo::mutex _clientsLock; static ClientCache _clients; static boost::thread_specific_ptr<ClientInfo> _tlInfo; }; diff --git a/s/s_only.cpp b/s/s_only.cpp index d692ff2..78310fd 100644 --- a/s/s_only.cpp +++ b/s/s_only.cpp @@ -18,6 +18,7 @@ #include "../stdafx.h" #include "../client/dbclient.h" #include "../db/dbhelpers.h" +#include "../db/matcher.h" namespace mongo { @@ -26,4 +27,7 @@ namespace mongo { auto_ptr<CursorIterator> i; return i; } + + // need this stub to reduce mongos link dependencies + inline Matcher::~Matcher() { assert(!"this shouldn't be called"); } } diff --git a/s/server.cpp b/s/server.cpp index 4868caf..3644376 100644 --- a/s/server.cpp +++ b/s/server.cpp @@ -30,10 +30,10 @@ namespace mongo { Database *database = 0; + string mongosCommand; string ourHostname; OID serverID; bool dbexitCalled = false; - CmdLine cmdLine; bool inShutdown(){ return dbexitCalled; @@ -47,12 +47,12 @@ namespace mongo { assert( 0 ); return false; } - + void usage( char * argv[] ){ out() << argv[0] << " usage:\n\n"; - out() << " -v+ verbose\n"; + out() << " -v+ verbose 1: general 2: more 3: per request 4: more\n"; out() << " --port <portno>\n"; - out() << " --configdb <configdbname> [<configdbname>...]\n"; + out() << " --configdb <configdbname>,[<configdbname>,<configdbname>]\n"; out() << endl; } @@ -88,10 +88,20 @@ namespace mongo { } } }; + + void sighandler(int sig){ + dbexit(EXIT_CLEAN, (string("recieved signal ") + BSONObjBuilder::numStr(sig)).c_str()); + } + void setupSignals(){ + // needed for cmdLine, btu we do it in init() + } + void init(){ serverID.init(); setupSIGTRAPforGDB(); + signal(SIGTERM, sighandler); + signal(SIGINT, sighandler); } void start() { @@ -108,55 +118,83 @@ namespace mongo { return 0; } + void printShardingVersionInfo(){ + log() << mongosCommand << " v0.3 (alpha 3) starting (--help for usage)" << endl; + printGitVersion(); + printSysInfo(); + } + } // namespace mongo using namespace mongo; +#include <boost/program_options.hpp> + +namespace po = boost::program_options; + int main(int argc, char* argv[], char *envp[] ) { + static StaticObserver staticObserver; + mongosCommand = argv[0]; + + po::options_description options("Sharding options"); + po::options_description hidden("Hidden options"); + po::positional_options_description positional; - bool justTests = false; - vector<string> configdbs; + CmdLine::addGlobalOptions( options , hidden ); - for (int i = 1; i < argc; i++) { - if ( argv[i] == 0 ) continue; - string s = argv[i]; - if ( s == "--port" ) { - cmdLine.port = atoi(argv[++i]); - } - else if ( s == "--configdb" ) { - - while ( ++i < argc ) - configdbs.push_back(argv[i]); - - if ( configdbs.size() == 0 ) { - out() << "error: no args for --configdb\n"; - return 4; - } - - if ( configdbs.size() > 2 ) { - out() << "error: --configdb does not support more than 2 parameters yet\n"; - return 5; - } - } - else if ( s.find( "-v" ) == 0 ){ - logLevel = s.size() - 1; - } - else if ( s == "--test" ) { - justTests = true; - logLevel = 5; - } - else { - usage( argv ); - return 3; - } - } + options.add_options() + ( "configdb" , po::value<string>() , "1 or 3 comma separated config servers" ) + ( "test" , "just run unit tests" ) + ; + + + // parse options + po::variables_map params; + if ( ! CmdLine::store( argc , argv , options , hidden , positional , params ) ) + return 0; - if ( justTests ){ + if ( params.count( "help" ) ){ + cout << options << endl; + return 0; + } + + if ( params.count( "version" ) ){ + printShardingVersionInfo(); + return 0; + } + + + if ( params.count( "test" ) ){ + logLevel = 5; UnitTest::runTests(); cout << "tests passed" << endl; return 0; } + if ( ! params.count( "configdb" ) ){ + out() << "error: no args for --configdb" << endl; + return 4; + } + + vector<string> configdbs; + { + string s = params["configdb"].as<string>(); + while ( true ){ + size_t idx = s.find( ',' ); + if ( idx == string::npos ){ + configdbs.push_back( s ); + break; + } + configdbs.push_back( s.substr( 0 , idx ) ); + s = s.substr( idx + 1 ); + } + } + + if ( configdbs.size() != 1 && configdbs.size() != 3 ){ + out() << "need either 1 or 3 configdbs" << endl; + return 5; + } + pool.addHook( &shardingConnectionHook ); if ( argc <= 1 ) { @@ -170,24 +208,26 @@ int main(int argc, char* argv[], char *envp[] ) { usage( argv ); return 1; } - - log() << argv[0] << " v0.3- (alpha 3t) starting (--help for usage)" << endl; - printGitVersion(); - printSysInfo(); + + printShardingVersionInfo(); if ( ! configServer.init( configdbs ) ){ cout << "couldn't connectd to config db" << endl; return 7; } - assert( configServer.ok() ); + if ( ! configServer.ok() ){ + cout << "configServer startup check failed" << endl; + return 8; + } int configError = configServer.checkConfigVersion(); if ( configError ){ cout << "config server error: " << configError << endl; return configError; } - + configServer.reloadSettings(); + init(); start(); dbexit( EXIT_CLEAN ); diff --git a/s/strategy.cpp b/s/strategy.cpp index b485bd2..b7277e3 100644 --- a/s/strategy.cpp +++ b/s/strategy.cpp @@ -1,3 +1,19 @@ +/* + * 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/>. + */ + // stragegy.cpp #include "stdafx.h" @@ -25,14 +41,12 @@ namespace mongo { void Strategy::doQuery( Request& r , string server ){ try{ ScopedDbConnection dbcon( server ); - DBClientBase &_c = dbcon.conn(); + DBClientBase &c = dbcon.conn(); - checkShardVersion( _c , r.getns() ); + checkShardVersion( c , r.getns() ); - // TODO: This will not work with Paired connections. Fix. - DBClientConnection&c = dynamic_cast<DBClientConnection&>(_c); Message response; - bool ok = c.port().call( r.m(), response); + bool ok = c.call( r.m(), response); { QueryResult *qr = (QueryResult *) response.data; diff --git a/s/strategy.h b/s/strategy.h index e4b93b5..a656f60 100644 --- a/s/strategy.h +++ b/s/strategy.h @@ -1,4 +1,20 @@ // strategy.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 diff --git a/s/strategy_shard.cpp b/s/strategy_shard.cpp index 34cf226..9107f16 100644 --- a/s/strategy_shard.cpp +++ b/s/strategy_shard.cpp @@ -1,3 +1,19 @@ +/* + * 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/>. + */ + // strategy_sharded.cpp #include "stdafx.h" diff --git a/s/strategy_single.cpp b/s/strategy_single.cpp index 9cf8a63..8f157d5 100644 --- a/s/strategy_single.cpp +++ b/s/strategy_single.cpp @@ -1,3 +1,19 @@ +/* + * 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/>. + */ + // strategy_simple.cpp #include "stdafx.h" @@ -35,6 +35,7 @@ namespace mongo { stringstream s; s << "StaleConfigException ns: " << ns << " " << msg; _msg = s.str(); + log(1) << _msg << endl; } virtual ~StaleConfigException() throw(){} |