summaryrefslogtreecommitdiff
path: root/s
diff options
context:
space:
mode:
authorAntonin Kral <a.kral@bobek.cz>2010-03-25 19:21:32 +0100
committerAntonin Kral <a.kral@bobek.cz>2010-03-25 19:21:32 +0100
commit0ca01a91ae0a3562e54c226e7b9512feb2ea83d0 (patch)
tree2b3886e435b0217d6afd63a213b04d32bb4b4f6f /s
parenta696359b248adef0cc8576fce3f473535e995136 (diff)
downloadmongodb-0ca01a91ae0a3562e54c226e7b9512feb2ea83d0.tar.gz
Imported Upstream version 1.4.0
Diffstat (limited to 's')
-rw-r--r--s/chunk.cpp45
-rw-r--r--s/chunk.h40
-rw-r--r--s/commands_admin.cpp10
-rw-r--r--s/commands_public.cpp158
-rw-r--r--s/config.cpp49
-rw-r--r--s/config.h4
-rw-r--r--s/cursors.cpp16
-rw-r--r--s/cursors.h16
-rw-r--r--s/d_logic.cpp11
-rw-r--r--s/d_logic.h16
-rw-r--r--s/dbgrid.vcproj44
-rw-r--r--s/request.cpp8
-rw-r--r--s/request.h18
-rw-r--r--s/s_only.cpp4
-rw-r--r--s/server.cpp132
-rw-r--r--s/strategy.cpp24
-rw-r--r--s/strategy.h16
-rw-r--r--s/strategy_shard.cpp16
-rw-r--r--s/strategy_single.cpp16
-rw-r--r--s/util.h1
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();
}
diff --git a/s/chunk.h b/s/chunk.h
index 7395133..25502e4 100644
--- a/s/chunk.h
+++ b/s/chunk.h
@@ -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 )
diff --git a/s/config.h b/s/config.h
index 16aa67a..3b0dc4c 100644
--- a/s/config.h
+++ b/s/config.h
@@ -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="&quot;..\pcre-7.4&quot;;&quot;C:\Program Files\boost\boost_1_35_0&quot;"
- 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"
diff --git a/s/util.h b/s/util.h
index ba40a29..2c62642 100644
--- a/s/util.h
+++ b/s/util.h
@@ -35,6 +35,7 @@ namespace mongo {
stringstream s;
s << "StaleConfigException ns: " << ns << " " << msg;
_msg = s.str();
+ log(1) << _msg << endl;
}
virtual ~StaleConfigException() throw(){}