Compare commits

...

51 Commits

Author SHA1 Message Date
Eliot Horowitz
c5f5f9a4f3 stabilize test 2010-08-17 12:28:19 -04:00
Alberto Lerner
19b587d925 Depend less an a time estimate. 2010-08-17 11:49:07 -04:00
Eliot Horowitz
31d81b823d BUMP 1.6.1 2010-08-17 10:04:43 -04:00
Eliot Horowitz
e280c561f1 make sharding/rs test faster 2010-08-17 09:57:17 -04:00
Eliot Horowitz
1a30dad111 turn off test that is different on windows 2010-08-17 09:34:29 -04:00
Eliot Horowitz
3770916e05 SERVER-1626 initial sync bug fix
Conflicts:

	db/repl.cpp
2010-08-16 17:07:08 -04:00
Eliot Horowitz
67159d2583 BackgroundJob::wait bug SERVER-1628
Conflicts:

	util/background.cpp
2010-08-16 17:04:22 -04:00
dwight
81da9cda7f faster 2010-08-16 17:03:38 -04:00
dwight
415c264123 SERVER-1614 2010-08-16 17:02:33 -04:00
Dwight
4454a8a0a0 fix help title 2010-08-16 16:57:23 -04:00
Eliot Horowitz
d1c3edcf33 writeback is ok on slave 2010-08-16 15:48:08 -04:00
Eliot Horowitz
1948efc6a4 cursor paranoia 2010-08-16 14:30:11 -04:00
Eliot Horowitz
c3855123b5 even more migrate debugging 2010-08-16 14:29:59 -04:00
Eliot Horowitz
2976396903 return connection to pool 2010-08-16 14:29:48 -04:00
Eliot Horowitz
aa5d314ae9 compile 2010-08-16 14:29:39 -04:00
Eliot Horowitz
d3b427b96f better transfer error logging 2010-08-16 14:29:29 -04:00
Eliot Horowitz
3de268fcae change error reporting order for robustness 2010-08-16 14:28:53 -04:00
Eliot Horowitz
54239a3676 fix select() timing for os x SERVER-1596 2010-08-16 14:28:12 -04:00
Eliot Horowitz
1d7dfe2868 try to fix select timing on windows SERVER-1596 2010-08-16 14:28:02 -04:00
Eliot Horowitz
f1f53ef3c1 possible chunk matcher fix 2010-08-16 14:27:43 -04:00
Eliot Horowitz
356eeb5a62 make BSONElement::toString 20x faster for double 2010-08-16 14:27:29 -04:00
Eliot Horowitz
2800a96e56 clean up chunk version handling - prep for SERVER-1473 2010-08-16 14:26:12 -04:00
Mathias Stearn
0c8f696e79 be smarter about sleeping 2010-08-16 14:25:59 -04:00
Alberto Lerner
b58d62a194 Bug fix: logChange() does't throw (can be called from destructors 2010-08-16 14:16:58 -04:00
Eliot Horowitz
2ba8ac25f1 CS-112 initial sync problem with traditional replication
Conflicts:

	db/repl.cpp
2010-08-12 16:12:02 -04:00
Mathias Stearn
edb14c522b move log flush code to after errnoWithDescription 2010-08-11 14:43:26 -04:00
Mathias Stearn
af35eebfb6 check return from fwrite SERVER-1578 2010-08-11 14:43:16 -04:00
Mathias Stearn
edffe867a5 distinct should yield even if non-matching. SERVER-1597 2010-08-09 14:45:12 -04:00
Mathias Stearn
0e8ef6bca0 Yield in distinct SERVER-1597 2010-08-09 14:45:03 -04:00
Mathias Stearn
b59584f3dd Support large files in GridFS SERVER-1408 2010-08-09 13:38:43 -04:00
Eliot Horowitz
3cc86177ce fix getMore with sharding+rs in edge case SERVER-1584 2010-08-06 13:25:52 -04:00
Alberto Lerner
dcfab78c4b DistributedLock::unlock() handles partition from config DB 2010-08-05 13:41:01 -04:00
Eliot Horowitz
ba166df412 post 1.6.0 2010-08-05 11:34:06 -04:00
Eliot Horowitz
2c7f164b65 BUMP 1.6.0 2010-08-05 09:32:06 -04:00
Alberto Lerner
53d1c8bbad Bug fix: DefaultDBPort is perfectly valid when transitioning from a non-sharded mongod 2010-08-05 00:16:50 -04:00
Eliot Horowitz
e4fcc800f7 fix serverStatus for replica sets SERVER-1570 2010-08-04 16:03:32 -04:00
Eliot Horowitz
7abf0580ca when restarting repl set don't blow away directories
Conflicts:

	shell/servers.js
2010-08-04 16:00:06 -04:00
Eliot Horowitz
ae1e0804da fix upsert with $atomic SERVER-1568 2010-08-04 15:15:30 -04:00
Mathias Stearn
50b7bbe934 Low-verbosity sharded explain() SERVER-1562 2010-08-04 13:30:47 -04:00
Eliot Horowitz
fd26b536e9 clean up data files after sharding/replset tests 2010-08-04 12:33:13 -04:00
Dwight
6f6aa20e92 trying to fix SERVER-1483 2010-08-04 12:13:38 -04:00
Dwight
55937a8f3e sort members in replSetGetStatus output for easy reading 2010-08-04 12:11:18 -04:00
Richard Kreuter
8947d06986 Remove C++ driver from RPM specfile. 2010-08-04 11:54:00 -04:00
Dwight
8c095b2cb2 make error msgs better 2010-08-04 11:53:56 -04:00
Dwight
2e6aeb0229 extraneous logging 2010-08-04 11:53:52 -04:00
Dwight
cb661f73fd allow a member down during a config change 2010-08-04 11:53:44 -04:00
Eliot Horowitz
63f894763d fix sorting if sort field not included in projection SERVER-1561 2010-08-04 11:53:36 -04:00
Eliot Horowitz
2c3d88336e allow get last errors blocking on w to be killed 2010-08-04 10:20:16 -04:00
Eliot Horowitz
c542dbd78a when access namespace for the first time, prep all connections SERVER-1560 2010-08-04 10:17:17 -04:00
Eliot Horowitz
b5ce278c18 fix type SERVER-1563 2010-08-04 09:39:16 -04:00
Eliot Horowitz
a432ac592e 1.6.0-pre- marker 2010-08-03 22:18:44 -04:00
53 changed files with 524 additions and 190 deletions

View File

@@ -387,16 +387,7 @@ namespace mongo {
}
break;
case NumberDouble:
{
stringstream tmp;
tmp.precision( 16 );
tmp << number();
string n = tmp.str();
s << n;
// indicate this is a double:
if( strchr(n.c_str(), '.') == 0 && strchr(n.c_str(), 'E') == 0 && strchr(n.c_str(), 'N') == 0 )
s << ".0";
}
s.appendDoubleNice( number() );
break;
case NumberLong:
s << _numberLong();

View File

@@ -164,6 +164,7 @@ namespace mongo {
#define SBNUM(val,maxSize,macro) \
int prev = _buf.l; \
int z = sprintf( _buf.grow(maxSize) , macro , (val) ); \
assert( z >= 0 ); \
_buf.l = prev + z; \
return *this;
@@ -197,6 +198,17 @@ namespace mongo {
}
#undef SBNUM
void appendDoubleNice( double x ){
int prev = _buf.l;
char * start = _buf.grow( 32 );
int z = sprintf( start , "%.16g" , x );
assert( z >= 0 );
_buf.l = prev + z;
if( strchr(start, '.') == 0 && strchr(start, 'E') == 0 && strchr(start, 'N') == 0 ){
write( ".0" , 2 );
}
}
void write( const char* buf, int len){
memcpy( _buf.grow( len ) , buf , len );
}

View File

@@ -1063,6 +1063,18 @@ namespace mongo {
return checkMaster()->findOne(a,b,c,d);
}
bool DBClientReplicaSet::isMember( const DBConnector * conn ) const {
if ( conn == this )
return true;
for ( unsigned i=0; i<_conns.size(); i++ )
if ( _conns[i]->isMember( conn ) )
return true;
return false;
}
bool serverAlive( const string &uri ) {
DBClientConnection c( false, 0, 20 ); // potentially the connection to server could fail while we're checking if it's alive - so use timeouts
string err;

View File

@@ -329,6 +329,8 @@ namespace mongo {
/* used by QueryOption_Exhaust. To use that your subclass must implement this. */
virtual void recv( Message& m ) { assert(false); }
virtual string getServerAddress() const = 0;
};
/**
@@ -739,8 +741,6 @@ namespace mongo {
*/
virtual void update( const string &ns , Query query , BSONObj obj , bool upsert = false , bool multi = false );
virtual string getServerAddress() const = 0;
virtual bool isFailed() const = 0;
virtual void killCursor( long long cursorID ) = 0;
@@ -758,6 +758,9 @@ namespace mongo {
virtual void say( Message& toSend ) = 0;
virtual ConnectionString::ConnectionType type() const = 0;
/** @return true if conn is either equal to or contained in this connection */
virtual bool isMember( const DBConnector * conn ) const = 0;
}; // DBClientBase
class DBClientReplicaSet;
@@ -892,11 +895,16 @@ namespace mongo {
virtual bool call( Message &toSend, Message &response, bool assertOk = true );
virtual ConnectionString::ConnectionType type() const { return ConnectionString::MASTER; }
virtual bool isMember( const DBConnector * conn ) const { return this == conn; };
virtual void checkResponse( const char *data, int nReturned );
protected:
friend class SyncClusterConnection;
virtual void recv( Message& m );
virtual void sayPiggyBack( Message &toSend );
virtual void checkResponse( const char *data, int nReturned );
};
/** Use this class to connect to a replica set of servers. The class will manage
@@ -987,9 +995,12 @@ namespace mongo {
virtual ConnectionString::ConnectionType type() const { return ConnectionString::SET; }
virtual bool isMember( const DBConnector * conn ) const;
virtual void checkResponse( const char *data, int nReturned ) { checkMaster()->checkResponse( data , nReturned ); }
protected:
virtual void sayPiggyBack( Message &toSend ) { assert(false); }
virtual void checkResponse( const char *data, int nReturned ) { assert(false); }
bool isFailed() const {
return _currentMaster == 0 || _currentMaster->isFailed();

View File

@@ -193,7 +193,7 @@ namespace mongo {
void DBClientCursor::attach( AScopedConnection * conn ){
assert( _scopedHost.size() == 0 );
assert( connector == conn->get() );
assert( conn->get()->isMember( connector ) );
_scopedHost = conn->getHost();
conn->done();
connector = 0;

View File

@@ -109,9 +109,6 @@ namespace mongo {
bool DistributedLock::lock_try( string why , BSONObj * other ){
// check for recrusive
assert( getState() == 0 );
ScopedDbConnection conn( _conn );
BSONObjBuilder queryBuilder;
@@ -136,7 +133,7 @@ namespace mongo {
return false;
}
Date_t elapsed = jsTime() - lastPing["ping"].Date(); // in ms
unsigned long long elapsed = jsTime() - lastPing["ping"].Date(); // in ms
elapsed = elapsed / ( 1000 * 60 ); // convert to minutes
if ( elapsed <= _takeoverMinutes ){
@@ -208,18 +205,33 @@ namespace mongo {
if ( ! gotLock )
return false;
_state.set( 1 );
return true;
}
void DistributedLock::unlock(){
ScopedDbConnection conn( _conn );
conn->update( _ns , _id, BSON( "$set" << BSON( "state" << 0 ) ) );
log(1) << "dist_lock unlock: " << conn->findOne( _ns , _id ) << endl;
conn.done();
const int maxAttempts = 3;
int attempted = 0;
while ( ++attempted <= maxAttempts ) {
try {
ScopedDbConnection conn( _conn );
conn->update( _ns , _id, BSON( "$set" << BSON( "state" << 0 ) ) );
log(1) << "dist_lock unlock: " << conn->findOne( _ns , _id ) << endl;
conn.done();
return;
_state.set( 0 );
} catch ( std::exception& e) {
log( LL_WARNING ) << "dist_lock " << _name << " failed to contact config server in unlock attempt "
<< attempted << ": " << e.what() << endl;
sleepsecs(1 << attempted);
}
}
log( LL_WARNING ) << "dist_lock couldn't consumate unlock request. " << "Lock " << _name
<< " will be taken over after " << _takeoverMinutes << " minutes timeout" << endl;
}
}

View File

@@ -36,14 +36,6 @@ namespace mongo {
*/
DistributedLock( const ConnectionString& conn , const string& name , unsigned takeoverMinutes = 10 );
int getState(){
return _state.get();
}
bool isLocked(){
return _state.get() != 0;
}
bool lock_try( string why , BSONObj * other = 0 );
void unlock();
@@ -54,8 +46,6 @@ namespace mongo {
string _ns;
BSONObj _id;
ThreadLocalValue<int> _state;
};
class dist_lock_try {

View File

@@ -66,7 +66,6 @@ namespace mongo {
}
BSONObj GridFS::storeFile( const char* data , size_t length , const string& remoteName , const string& contentType){
massert( 10279 , "large files not yet implemented", length <= 0xffffffff);
char const * const end = data + length;
OID id;
@@ -127,8 +126,6 @@ namespace mongo {
if (fd != stdin)
fclose( fd );
massert( 10280 , "large files not yet implemented", length <= 0xffffffff);
return insertFile((remoteName.empty() ? fileName : remoteName), id, length, contentType);
}

View File

@@ -328,6 +328,38 @@ namespace mongo {
void ParallelSortClusteredCursor::_finishCons(){
_numServers = _servers.size();
_cursors = 0;
if ( ! _sortKey.isEmpty() && ! _fields.isEmpty() ){
// we need to make sure the sort key is in the project
bool isNegative = false;
BSONObjBuilder b;
{
BSONObjIterator i( _fields );
while ( i.more() ){
BSONElement e = i.next();
b.append( e );
if ( ! e.trueValue() )
isNegative = true;
}
}
{
BSONObjIterator i( _sortKey );
while ( i.more() ){
BSONElement e = i.next();
BSONElement f = _fields.getField( e.fieldName() );
if ( isNegative ){
uassert( 13431 , "have to have sort key in projection and removing it" , f.eoo() );
}
else if ( f.eoo() ){
// add to projection
b.append( e );
}
}
}
_fields = b.obj();
}
}
void ParallelSortClusteredCursor::_init(){

View File

@@ -369,4 +369,16 @@ namespace mongo {
// should never need to do this
assert(0);
}
bool SyncClusterConnection::isMember( const DBConnector * conn ) const {
if ( conn == this )
return true;
for ( unsigned i=0; i<_conns.size(); i++ )
if ( _conns[i]->isMember( conn ) )
return true;
return false;
}
}

View File

@@ -90,6 +90,8 @@ namespace mongo {
virtual ConnectionString::ConnectionType type() const { return ConnectionString::SYNC; }
virtual bool isMember( const DBConnector * conn ) const;
private:
SyncClusterConnection( SyncClusterConnection& prev );
string _toString() const;

View File

@@ -126,6 +126,7 @@ namespace mongo {
assert( sprintf( buf , "w block pass: %lld" , ++passes ) < 30 );
c.curop()->setMessage( buf );
sleepmillis(1);
killCurrentOp.checkForInterrupt();
}
result.appendNumber( "wtime" , t.millis() );
}
@@ -1450,17 +1451,18 @@ namespace mongo {
BSONElementSet values;
shared_ptr<Cursor> cursor = bestGuessCursor(ns.c_str() , query , BSONObj() );
scoped_ptr<ClientCursor> cc (new ClientCursor(QueryOption_NoCursorTimeout, cursor, ns));
while ( cursor->ok() ){
if ( cursor->matcher() && ! cursor->matcher()->matchesCurrent( cursor.get() ) ){
cursor->advance();
continue;
if ( !cursor->matcher() || cursor->matcher()->matchesCurrent( cursor.get() ) ){
BSONObj o = cursor->current();
o.getFieldsDotted( key, values );
}
BSONObj o = cursor->current();
cursor->advance();
o.getFieldsDotted( key.c_str(), values );
if (!cc->yieldSometimes())
break;
}
BSONArrayBuilder b( result.subarrayStart( "values" ) );

View File

@@ -432,7 +432,7 @@ namespace mongo {
ss << p( a("/", "back", "Home") );
ss << p( "<b>MongoDB List of <a href=\"http://www.mongodb.org/display/DOCS/Commands\">Commands</a></b>\n" );
const map<string, Command*> *m = Command::commandsByBestName();
ss << "S:slave-only N:no-lock R:read-lock W:write-lock A:admin-only<br>\n";
ss << "S:slave-ok R:read-lock W:write-lock A:admin-only<br>\n";
ss << table();
ss << "<tr><th>Command</th><th>Attributes</th><th>Help</th></tr>\n";
for( map<string, Command*>::const_iterator i = m->begin(); i != m->end(); i++ )

View File

@@ -143,6 +143,7 @@ namespace mongo {
}
virtual ConnectionString::ConnectionType type() const { return ConnectionString::MASTER; }
virtual bool isMember( const DBConnector * conn ) const { return this == conn; };
};
extern int lockFile;

View File

@@ -637,6 +637,8 @@ namespace mongo {
}
bool legalClientSystemNS( const string& ns , bool write ){
if( ns == "local.system.replset" ) return true;
if ( ns.find( ".system.users" ) != string::npos )
return true;

View File

@@ -290,11 +290,13 @@ namespace mongo {
}
}
else {
result.append("ismaster", replSettings.master || replSettings.slave == 0 ? 1 : 0);
//result.append("msg", "not paired");
result.appendBool("ismaster", _isMaster() );
}
if ( level ){
if ( level && replSet ){
result.append( "info" , "is replica set" );
}
else if ( level ){
BSONObjBuilder sources( result.subarrayStart( "sources" ) );
readlock lk( "local.sources" );
@@ -856,11 +858,13 @@ namespace mongo {
see logOp() comments.
*/
void ReplSource::sync_pullOpLog_applyOperation(BSONObj& op, OpTime *localLogTail) {
log( 6 ) << "processing op: " << op << endl;
if( logLevel >= 6 ) // op.tostring is expensive so doing this check explicitly
log(6) << "processing op: " << op << endl;
// skip no-op
if ( op.getStringField( "op" )[ 0 ] == 'n' )
if( op.getStringField("op")[0] == 'n' )
return;
char clientName[MaxDatabaseLen];
const char *ns = op.getStringField("ns");
nsToDatabase(ns, clientName);
@@ -1301,12 +1305,15 @@ namespace mongo {
1) find most recent op in local log
2) more()?
*/
if ( !oplogReader.more() ) {
bool moreInitialSyncsPending = !addDbNextPass.empty() && n; // we need "&& n" to assure we actually process at least one op to get a sync point recorded in the first place.
if ( moreInitialSyncsPending || !oplogReader.more() ) {
dblock lk;
OpTime nextLastSaved = nextLastSavedLocalTs();
{
dbtemprelease t;
if ( oplogReader.more() ) {
if ( !moreInitialSyncsPending && oplogReader.more() ) {
if ( getInitialSyncCompleted() ) { // if initial sync hasn't completed, break out of loop so we can set to completed or clone more dbs
continue;
}
@@ -1323,6 +1330,8 @@ namespace mongo {
log() << "repl: end sync_pullOpLog syncedTo: " << syncedTo.toStringLong() << endl;
break;
}
else {
}
OCCASIONALLY if( n > 0 && ( n > 100000 || time(0) - saveLast > 60 ) ) {
// periodically note our progress, in case we are doing a lot of work and crash

View File

@@ -171,7 +171,7 @@ namespace mongo {
}
void ReplSetImpl::_getOplogDiagsAsHtml(unsigned server_id, stringstream& ss) const {
Member *m = findById(server_id);
const Member *m = findById(server_id);
if( m == 0 ) {
ss << "Error : can't find a member with id: " << server_id << '\n';
return;
@@ -329,7 +329,7 @@ namespace mongo {
_rsLog.toHTML( s );
}
Member* ReplSetImpl::findById(unsigned id) const {
const Member* ReplSetImpl::findById(unsigned id) const {
if( id == _self->id() ) return _self;
for( Member *m = head(); m; m = m->next() )
if( m->id() == id )
@@ -371,6 +371,7 @@ namespace mongo {
v.push_back(bb.obj());
m = m->next();
}
sort(v.begin(), v.end());
b.append("set", name());
b.appendTimeT("date", time(0));
b.append("myState", box.getState().s);

View File

@@ -26,7 +26,7 @@
namespace mongo {
void checkAllMembersUpForConfigChange(const ReplSetConfig& cfg, bool initial);
void checkMembersUpForConfigChange(const ReplSetConfig& cfg, bool initial);
/* commands in other files:
replSetHeartbeat - health.cpp
@@ -151,9 +151,9 @@ namespace mongo {
return false;
}
checkAllMembersUpForConfigChange(newConfig,false);
checkMembersUpForConfigChange(newConfig,false);
log() << "replSet replSetReconfig all members seem up" << rsLog;
log() << "replSet replSetReconfig [2]" << rsLog;
theReplSet->haveNewConfig(newConfig, true);
ReplSet::startupStatusMsg = "replSetReconfig'd";

View File

@@ -390,9 +390,9 @@ namespace mongo {
startupStatus = EMPTYCONFIG;
startupStatusMsg = "can't get " + rsConfigNs + " config from self or any seed (EMPTYCONFIG)";
log() << "replSet can't get " << rsConfigNs << " config from self or any seed (EMPTYCONFIG)" << rsLog;
log() << "replSet have you ran replSetInitiate yet?" << rsLog;
log(1) << "replSet have you ran replSetInitiate yet?" << rsLog;
if( _seeds->size() == 0 )
log() << "replSet no seed hosts were specified on the --replSet command line - that might be the issue" << rsLog;
log(1) << "replSet info no seed hosts were specified on the --replSet command line" << rsLog;
}
else {
startupStatus = EMPTYUNREACHABLE;

View File

@@ -305,7 +305,9 @@ namespace mongo {
private:
Member* head() const { return _members.head(); }
Member* findById(unsigned id) const;
public:
const Member* findById(unsigned id) const;
private:
void _getTargets(list<Target>&, int &configVersion);
void getTargets(list<Target>&, int &configVersion);
void startThreads();

View File

@@ -114,7 +114,7 @@ namespace mongo {
mchk(_id >= 0 && _id <= 255);
mchk(priority >= 0 && priority <= 1000);
mchk(votes >= 0 && votes <= 100);
uassert(13419, "replica set config : this version of mongo only supports priorities 0 and 1", priority == 0 || priority == 1);
uassert(13419, "this version of mongod only supports priorities 0 and 1", priority == 0 || priority == 1);
}
/*static*/ bool ReplSetConfig::legalChange(const ReplSetConfig& o, const ReplSetConfig& n, string& errmsg) {
@@ -133,7 +133,7 @@ namespace mongo {
/* TODO : MORE CHECKS HERE */
cout << "TODO : don't allow removal of a node until we handle it at the removed node end." << endl;
log() << "replSet TODO : don't allow removal of a node until we handle it at the removed node end?" << endl;
// we could change its votes to zero perhaps instead as a short term...
return true;
@@ -220,7 +220,7 @@ namespace mongo {
catch(DBException& e) {
log() << "replSet cfg parsing exception for members[" << i << "] " << e.what() << rsLog;
stringstream ss;
ss << "replSet members[" << i << "] bad config object";
ss << "bad config for member[" << i << "] " << e.what();
uassert(13135, ss.str(), false);
}
if( !(ords.count(m._id) == 0 && hosts.count(m.h.toString()) == 0) ) {

View File

@@ -32,10 +32,12 @@ using namespace mongoutils;
namespace mongo {
/* throws
@param initial -
/* called on a reconfig AND on initiate
throws
@param initial true when initiating
*/
void checkAllMembersUpForConfigChange(const ReplSetConfig& cfg, bool initial) {
void checkMembersUpForConfigChange(const ReplSetConfig& cfg, bool initial) {
int failures = 0;
int me = 0;
for( vector<ReplSetConfig::MemberCfg>::const_iterator i = cfg.members.begin(); i != cfg.members.end(); i++ ) {
if( i->h.isSelf() ) {
@@ -45,7 +47,7 @@ namespace mongo {
}
}
}
uassert(13278, "bad config?", me <= 1);
uassert(13278, "bad config - dups?", me <= 1); // dups?
uassert(13279, "can't find self in the replset config", me == 1);
for( vector<ReplSetConfig::MemberCfg>::const_iterator i = cfg.members.begin(); i != cfg.members.end(); i++ ) {
@@ -62,12 +64,11 @@ namespace mongo {
}
}
catch(DBException& e) {
log() << "replSet requestHeartbeat " << i->h.toString() << " : " << e.toString() << rsLog;
log() << "replSet cmufcc requestHeartbeat " << i->h.toString() << " : " << e.toString() << rsLog;
}
catch(...) {
log() << "replSet error exception in requestHeartbeat?" << rsLog;
log() << "replSet cmufcc error exception in requestHeartbeat?" << rsLog;
}
cout << "TEMP hb res cfg change:" << res.toString() << endl;
if( res.getBoolField("mismatch") )
uasserted(13145, "set name does not match the set name host " + i->h.toString() + " expects");
if( *res.getStringField("set") ) {
@@ -83,9 +84,31 @@ namespace mongo {
}
}
if( !ok && !res["rs"].trueValue() ) {
if( !res.isEmpty() )
if( !res.isEmpty() ) {
/* strange. got a response, but not "ok". log it. */
log() << "replSet warning " << i->h.toString() << " replied: " << res.toString() << rsLog;
uasserted(13144, "need members up to initiate/reconfig, not ok: " + i->h.toString());
}
bool allowFailure = false;
failures++;
if( res.isEmpty() && !initial && failures == 1 ) {
/* for now we are only allowing 1 node to be down on a reconfig. this can be made to be a minority
trying to keep change small as release is near.
*/
const Member* m = theReplSet->findById( i->_id );
if( m ) {
// ok, so this was an existing member (wouldn't make sense to add to config a new member that is down)
assert( m->h().toString() == i->h.toString() );
allowFailure = true;
}
}
if( !allowFailure ) {
string msg = string("need members up to initiate, not ok : ") + i->h.toString();
if( !initial )
msg = string("need most members up to reconfigure, not ok : ") + i->h.toString();
uasserted(13144, msg);
}
}
}
if( initial ) {
@@ -175,8 +198,10 @@ namespace mongo {
configObj = cmdObj["replSetInitiate"].Obj();
}
bool parsed = false;
try {
ReplSetConfig newConfig(configObj);
parsed = true;
if( newConfig.version > 1 ) {
errmsg = "can't initiate with a version number greater than 1";
@@ -185,7 +210,7 @@ namespace mongo {
log() << "replSet replSetInitiate config object parses ok, " << newConfig.members.size() << " members specified" << rsLog;
checkAllMembersUpForConfigChange(newConfig, true);
checkMembersUpForConfigChange(newConfig, true);
log() << "replSet replSetInitiate all members seem up" << rsLog;
@@ -199,7 +224,11 @@ namespace mongo {
}
catch( DBException& e ) {
log() << "replSet replSetInitiate exception: " << e.what() << rsLog;
throw;
if( !parsed )
errmsg = string("couldn't parse cfg object ") + e.what();
else
errmsg = string("couldn't initiate : ") + e.what();
return false;
}
return true;

View File

@@ -203,8 +203,8 @@ namespace mongo {
OpTime ts = o["ts"]._opTime();
long long h = o["h"].numberLong();
if( ts != lastOpTimeWritten || h != lastH ) {
log() << "TEMP our last op time written: " << lastOpTimeWritten.toStringPretty() << endl;
log() << "TEMP primary's GTE: " << ts.toStringPretty() << endl;
log(1) << "TEMP our last op time written: " << lastOpTimeWritten.toStringPretty() << endl;
log(1) << "TEMP primary's GTE: " << ts.toStringPretty() << endl;
/*
}*/
@@ -243,7 +243,6 @@ namespace mongo {
}
else {
sethbmsg(str::stream() << "still syncing, not yet to minValid optime " << minvalid.toString());
//log() << "TEMP " << lastOpTimeWritten.toString() << rsLog;
}
/* todo: too stale capability */

View File

@@ -613,6 +613,8 @@ namespace mongo {
BSONObjIteratorSorted i( query );
while ( i.more() ){
BSONElement e = i.next();
if ( e.fieldName()[0] == '$' ) // for $atomic and anything else we add
continue;
if ( e.type() == Object && e.embeddedObject().firstElement().fieldName()[0] == '$' ){
// this means this is a $gt type filter, so don't make part of the new object

View File

@@ -389,6 +389,35 @@ namespace JsobjTests {
}
};
class ToStringNumber {
public:
void run(){
BSONObjBuilder b;
b.append( "a" , (int)4 );
b.append( "b" , (double)5 );
b.append( "c" , (long long)6 );
b.append( "d" , 123.456789123456789123456789123456789 );
b.append( "e" , 123456789.123456789123456789123456789 );
b.append( "f" , 1234567891234567891234.56789123456789 );
b.append( "g" , -123.456 );
BSONObj x = b.obj();
ASSERT_EQUALS( "4", x["a"].toString( false , true ) );
ASSERT_EQUALS( "5.0", x["b"].toString( false , true ) );
ASSERT_EQUALS( "6", x["c"].toString( false , true ) );
ASSERT_EQUALS( "123.4567891234568" , x["d"].toString( false , true ) );
ASSERT_EQUALS( "123456789.1234568" , x["e"].toString( false , true ) );
// ASSERT_EQUALS( "1.234567891234568e+21" , x["f"].toString( false , true ) ); // windows and *nix are different - TODO, work around for test or not bother?
ASSERT_EQUALS( "-123.456" , x["g"].toString( false , true ) );
}
};
class NullString {
public:
void run() {
@@ -1693,6 +1722,7 @@ namespace JsobjTests {
add< BSONObjTests::AppendIntOrLL >();
add< BSONObjTests::AppendNumber >();
add< BSONObjTests::ToStringArray >();
add< BSONObjTests::ToStringNumber >();
add< BSONObjTests::NullString >();
add< BSONObjTests::Validation::BadType >();
add< BSONObjTests::Validation::EooBeforeEnd >();

11
debian/changelog vendored
View File

@@ -1,3 +1,14 @@
mongodb (1.6.0) unstable; urgency=low
* replica_sets some fixes
* sharding some fixes with rs
* full change log http://jira.mongodb.org/browse/SERVER/fixforversion/10183
mongodb (1.6.0) unstable; urgency=low
* sharding stable
* replica_sets stable
mongodb (1.5.8) unstable; urgency=low
* sharding lots of changes

View File

@@ -3,7 +3,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = MongoDB
PROJECT_NUMBER = 1.5.8
PROJECT_NUMBER = 1.6.1
OUTPUT_DIRECTORY = docs/doxygen
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English

View File

@@ -21,4 +21,10 @@ assert( res.databases && res.databases.length > 0 , "listDatabases 1 " + tojson(
x = db._adminCommand( "ismaster" );
assert( x.ismaster , "ismaster failed: " + tojson( x ) )
before = db.runCommand( "serverStatus" )
sleep( 5000 )
after = db.runCommand( "serverStatus" )
assert.lt( 3 , after.uptimeEstimate , "up1" )
assert.gt( after.uptimeEstimate , before.uptimeEstimate , "up2" )
// TODO: add more tests here

View File

@@ -141,6 +141,14 @@ assert.soon( function(){ return am.lotOfIndexes.getIndexes().length == as.lotOfI
assert.eq( am.lotOfIndexes.getIndexes().length , as.lotOfIndexes.getIndexes().length , "lots of indexes b" )
// multi-update with $inc
am.mu1.update( { _id : 1 , $atomic : 1 } , { $inc : { x : 1 } } , true , true )
x = { _id : 1 , x : 1 }
assert.eq( x , am.mu1.findOne() , "mu1" );
assert.soon( function(){ z = as.mu1.findOne(); printjson( z ); return friendlyEqual( x , z ); } , "mu2" )
rt.stop();

View File

@@ -27,7 +27,7 @@ doTest = function( signal ) {
var master = replTest.getMaster();
var config = master.getDB("local").system.replset.findOne();
replTest.stopSet( signal );
replTest.stopSet( signal , true );
replTest.restart(0);
replTest.restart(1);

View File

@@ -6,8 +6,14 @@ s.adminCommand( { shardcollection : "test.data" , key : { num : 1 } } );
db = s.getDB( "test" );
for ( i=0; i<100; i++ ){
db.data.insert( { _id : i , num : i } );
N = 100
forward = []
backward = []
for ( i=0; i<N; i++ ){
db.data.insert( { _id : i , num : i , x : N - i } )
forward.push( i )
backward.push( ( N - 1 ) - i )
}
db.getLastError();
@@ -23,7 +29,7 @@ assert.eq( temp[0].shard , temp[2].shard , "A2" );
assert.neq( temp[0].shard , temp[1].shard , "A3" );
temp = db.data.find().sort( { num : 1 } ).toArray();
assert.eq( 100 , temp.length , "B1" );
assert.eq( N , temp.length , "B1" );
for ( i=0; i<100; i++ ){
assert.eq( i , temp[i].num , "B2" )
}
@@ -39,6 +45,37 @@ assert.eq( 67 , z.length , "C2" )
print( "a: " + a + " b:" + b + " mongos slow down: " + Math.ceil( 100 * ( ( a - b ) / b ) ) + "%" )
//assert.lt( a , b * 1.3 , "C3 - speed test" );
// -- secondary index sorting
function getSorted( by , want , dir , proj ){
var s = {}
s[by] = dir || 1;
printjson( s )
var cur = db.data.find( {} , proj || {} ).sort( s )
return terse( cur.map( function(z){ return z[want]; } ) );
}
function terse( a ){
var s = "";
for ( var i=0; i<a.length; i++ ){
if ( i > 0 )
s += ",";
s += a[i];
}
return s;
}
forward = terse(forward);
backward = terse(backward);
assert.eq( forward , getSorted( "num" , "num" , 1 ) , "D1" )
assert.eq( backward , getSorted( "num" , "num" , -1 ) , "D2" )
assert.eq( backward , getSorted( "x" , "num" , 1 ) , "D3" )
assert.eq( forward , getSorted( "x" , "num" , -1 ) , "D4" )
assert.eq( backward , getSorted( "x" , "num" , 1 , { num : 1 } ) , "D5" )
assert.eq( forward , getSorted( "x" , "num" , -1 , { num : 1 } ) , "D6" )
s.stop();

View File

@@ -15,7 +15,7 @@ while ( bigString.length < 10000 )
inserted = 0;
num = 0;
while ( inserted < ( 20 * 1024 * 1024 ) ){
db.foo.insert( { _id : num++ , s : bigString } );
db.foo.insert( { _id : num++ , s : bigString , x : Math.random() } );
inserted += bigString.length;
}
@@ -48,6 +48,7 @@ assert.soon( function(){
return d < 5;
} , "balance didn't happen" , 1000 * 60 * 3 , 5000 );
s.config.settings.update( { _id: "balancer" }, { $set : { stopped: true } } , true );
for ( i=0; i<s._rs.length; i++ ){
r = s._rs[i];
@@ -58,4 +59,14 @@ for ( i=0; i<s._rs.length; i++ ){
assert.eq( x.master.md5 , x.slaves[j].md5 , "hashes same for: " + r.url + " slave: " + j );
}
assert.eq( num , db.foo.find().count() , "C1" )
assert.eq( num , db.foo.find().itcount() , "C2" )
assert.eq( num , db.foo.find().sort( { _id : 1 } ).itcount() , "C3" )
assert.eq( num , db.foo.find().sort( { _id : -1 } ).itcount() , "C4" )
db.foo.ensureIndex( { x : 1 } )
assert.eq( num , db.foo.find().sort( { x : 1 } ).itcount() , "C5" )
assert.eq( num , db.foo.find().sort( { x : -1 } ).itcount() , "C6" )
s.stop()

View File

@@ -1,5 +1,5 @@
Name: mongo
Version: 1.5.8
Version: 1.6.1
Release: mongodb_1%{?dist}
Summary: mongo client shell and tools
License: AGPL 3.0
@@ -130,11 +130,6 @@ fi
%attr(0755,mongod,mongod) %dir /var/log/mongo
%attr(0640,mongod,mongod) %config(noreplace) %verify(not md5 size mtime) /var/log/mongo/mongod.log
%files devel
/usr/include/mongo
%{_libdir}/libmongoclient.a
#%{_libdir}/libmongotestfiles.a
%changelog
* Thu Jan 28 2010 Richard M Kreuter <richard@10gen.com>
- Minor fixes.

View File

@@ -265,7 +265,7 @@ namespace mongo {
}
// Save the new key boundaries in the configDB.
_manager->save();
_manager->save( false );
// Log all these changes in the configDB's log. We log a simple split differently than a multi-split.
if ( newChunks.size() == 1) {
@@ -584,7 +584,7 @@ namespace mongo {
_shards.insert(c->getShard());
save_inlock();
save_inlock( true );
log() << "no chunks for:" << ns << " so creating first: " << c->toString() << endl;
}
}
@@ -880,16 +880,18 @@ namespace mongo {
configServer.logChange( "dropCollection" , _ns , BSONObj() );
}
void ChunkManager::save(){
void ChunkManager::save( bool major ){
rwlock lk( _lock , true );
save_inlock();
save_inlock( major );
}
void ChunkManager::save_inlock(){
void ChunkManager::save_inlock( bool major ){
ShardChunkVersion a = getVersion_inlock();
assert( a > 0 || _chunkMap.size() <= 1 );
ShardChunkVersion nextChunkVersion = a.incMajor();
ShardChunkVersion nextChunkVersion = a;
nextChunkVersion.inc( major );
vector<ChunkPtr> toFix;
vector<ShardChunkVersion> newVersions;
@@ -907,7 +909,7 @@ namespace mongo {
_sequenceNumber = ++NextSequenceNumber;
ShardChunkVersion myVersion = nextChunkVersion;
++nextChunkVersion;
nextChunkVersion.incMinor();
toFix.push_back( c );
newVersions.push_back( myVersion );

View File

@@ -269,7 +269,7 @@ namespace mongo {
void getAllShards( set<Shard>& all );
void getShardsForRange(set<Shard>& shards, const BSONObj& min, const BSONObj& max); // [min, max)
void save();
void save( bool major );
string toString() const;
@@ -307,7 +307,7 @@ namespace mongo {
void _reload_inlock();
void _load();
void save_inlock();
void save_inlock( bool major );
ShardChunkVersion getVersion_inlock() const;
void ensureIndex_inlock();

View File

@@ -624,8 +624,7 @@ namespace mongo {
return false;
}
// HostAndPort defaults to a different port; adjust if needed.
if ( shardAddr.port() == CmdLine::DefaultDBPort ){
if ( ! shardAddr.hasPort() ){
shardAddr.setPort( CmdLine::ShardServerPort );
}

View File

@@ -653,7 +653,13 @@ namespace mongo {
BSONObj msg = BSON( "_id" << id.str() << "server" << getHostNameCached() << "time" << DATENOW <<
"what" << what << "ns" << ns << "details" << detail );
log() << "config change: " << msg << endl;
conn->insert( "config.changelog" , msg );
try {
conn->insert( "config.changelog" , msg );
}
catch ( std::exception& e ){
log() << "not logging config change: " << e.what() << endl;
}
conn.done();
}

View File

@@ -528,7 +528,8 @@ namespace mongo {
log(0) << "_recvChunkStatus : " << res << endl;
if ( ! ok ){
if ( ! ok || res["state"].String() == "fail" ){
log( LL_ERROR ) << "_recvChunkStatus error : " << res << endl;
errmsg = "_recvChunkStatus error";
result.append( "cause" ,res );
return false;
@@ -544,7 +545,7 @@ namespace mongo {
// 5.a
migrateFromStatus._inCriticalSection = true;
ShardChunkVersion myVersion = maxVersion;
++myVersion;
myVersion.incMajor();
{
dblock lk;
@@ -587,7 +588,8 @@ namespace mongo {
if ( ! x.isEmpty() ){
BSONObjBuilder temp2;
++myVersion;
myVersion.incMinor();
temp2.appendTimestamp( "lastmod" , myVersion );
shardingState.setVersion( ns , myVersion );
@@ -685,10 +687,12 @@ namespace mongo {
catch ( std::exception& e ){
state = FAIL;
errmsg = e.what();
log( LL_ERROR ) << "migrate failed: " << e.what() << endl;
}
catch ( ... ){
state = FAIL;
errmsg = "UNKNOWN ERROR";
log( LL_ERROR ) << "migrate failed with unknown exception" << endl;
}
active = false;
}
@@ -739,7 +743,7 @@ namespace mongo {
auto_ptr<DBClientCursor> cursor = conn->query( ns , Query().minKey( min ).maxKey( max ) , /* QueryOption_Exhaust */ 0 );
assert( cursor.get() );
while ( cursor->more() ){
BSONObj o = cursor->next();
BSONObj o = cursor->next().getOwned();
{
writelock lk( ns );
Helpers::upsert( ns , o );
@@ -756,7 +760,11 @@ namespace mongo {
BSONObj res;
if ( ! conn->runCommand( "admin" , BSON( "_transferMods" << 1 ) , res ) ){
state = FAIL;
errmsg = "_transferMods failed: ";
errmsg += res.toString();
log( LL_ERROR ) << "_transferMods failed: " << res << endl;
conn.done();
return;
}
if ( res["size"].number() == 0 )
break;
@@ -775,6 +783,7 @@ namespace mongo {
log() << "_transferMods failed in STEADY state: " << res << endl;
errmsg = res.toString();
state = FAIL;
conn.done();
return;
}
@@ -801,9 +810,10 @@ namespace mongo {
b.append( "from" , from );
b.append( "min" , min );
b.append( "max" , max );
b.append( "state" , stateString() );
if ( state == FAIL )
b.append( "errmsg" , errmsg );
{
BSONObjBuilder bb( b.subobjStart( "counts" ) );
bb.append( "cloned" , numCloned );

View File

@@ -603,7 +603,8 @@ namespace mongo {
BSONObj x = loc.obj().extractFields(_key);
MyMap::const_iterator a = _map.upper_bound( x );
a--;
if ( a != _map.begin() )
a--;
bool good = x.woCompare( a->second.first ) >= 0 && x.woCompare( a->second.second ) < 0;
#if 0

View File

@@ -52,7 +52,7 @@ namespace mongo {
class WriteBackCommand : public Command {
public:
virtual LockType locktype() const { return NONE; }
virtual bool slaveOk() const { return false; }
virtual bool slaveOk() const { return true; }
virtual bool adminOnly() const { return true; }
WriteBackCommand() : Command( "writebacklisten" ){}

View File

@@ -123,7 +123,8 @@ namespace mongo {
log() << staleConfig.what() << " attempt: " << attempt << endl;
uassert( 10195 , "too many attempts to update config, failing" , attempt < 5 );
ShardConnection::checkMyConnectionVersions( getns() );
sleepsecs( attempt );
if (!staleConfig.justConnection() )
sleepsecs( attempt );
reset( ! staleConfig.justConnection() );
_d.markReset();
process( attempt + 1 );

View File

@@ -92,10 +92,12 @@ namespace mongo {
r.process();
}
catch ( DBException& e ){
log() << "DBException in process: " << e.what() << endl;
le->raiseError( e.getCode() , e.what() );
m.header()->id = r.id();
log() << "UserException: " << e.what() << endl;
if ( r.expectResponse() ){
BSONObj err = BSON( "$err" << e.what() << "code" << e.getCode() );
replyToQuery( ResultFlag_ErrSet, p , m , err );

View File

@@ -26,6 +26,7 @@ namespace mongo {
/**
* holds all the actual db connections for a client to various servers
* 1 pre thread, so don't have to worry about thread safety
*/
class ClientConnections : boost::noncopyable {
public:
@@ -70,7 +71,8 @@ namespace mongo {
_hosts.clear();
}
DBClientBase * get( const string& addr ){
DBClientBase * get( const string& addr , const string& ns ){
_check( ns );
scoped_lock lk( _mutex );
Status* &s = _hosts[addr];
if ( ! s )
@@ -152,9 +154,16 @@ namespace mongo {
}
}
void _check( const string& ns ){
if ( ns.size() == 0 || _seenNS.count( ns ) )
return;
_seenNS.insert( ns );
checkVersions( ns );
}
map<string,Status*> _hosts;
mongo::mutex _mutex;
set<string> _seenNS;
// -----
static thread_specific_ptr<ClientConnections> _perThread;
@@ -188,7 +197,7 @@ namespace mongo {
void ShardConnection::_init(){
assert( _addr.size() );
_conn = ClientConnections::get()->get( _addr );
_conn = ClientConnections::get()->get( _addr , _ns );
_finishedInit = false;
}

View File

@@ -58,11 +58,19 @@ namespace mongo {
}
}
ShardChunkVersion incMajor() const {
return ShardChunkVersion( _major + 1 , 0 );
void inc( bool major ){
if ( major )
incMajor();
else
incMinor();
}
void operator++(){
void incMajor() {
_major++;
_minor = 0;
}
void incMinor() {
_minor++;
}
@@ -79,8 +87,9 @@ namespace mongo {
ss << _major << "|" << _minor;
return ss.str();
}
operator unsigned long long() const { return _combined; }
ShardChunkVersion& operator=( const BSONElement& elem ){
switch ( elem.type() ){
case Timestamp:

View File

@@ -243,6 +243,20 @@ DBQuery.prototype.explain = function (verbose) {
if (!verbose) {
delete e.allPlans;
delete e.oldPlan;
if (e.shards){
for (var key in e.shards){
var s = e.shards[key];
if(s.length === undefined){
delete s.allPlans;
delete s.oldPlan;
} else {
for (var i=0; i < s.length; i++){
delete s[i].allPlans;
delete s[i].oldPlan;
}
}
}
}
}
return e;
}

View File

@@ -157,6 +157,9 @@ ShardingTest = function( testName , numShards , verboseLevel , numMongos , other
var localhost = "localhost";
this._alldbpaths = []
if ( otherParams.rs ){
localhost = getHostName();
// start replica sets
@@ -165,6 +168,11 @@ ShardingTest = function( testName , numShards , verboseLevel , numMongos , other
var rs = new ReplSetTest( { name : testName + "-rs" + i , nodes : 3 , startPort : 31100 + ( i * 100 ) } );
this._rs[i] = { test : rs , nodes : rs.startSet( { oplogSize:40 } ) , url : rs.getURL() };
rs.initiate();
}
for ( var i=0; i<numShards; i++){
var rs = this._rs[i].test;
rs.getMaster().getDB( "admin" ).foo.save( { x : 1 } )
rs.awaitReplication();
this._connections.push( new Mongo( rs.getURL() ) );
@@ -173,6 +181,7 @@ ShardingTest = function( testName , numShards , verboseLevel , numMongos , other
this._configServers = []
for ( var i=0; i<3; i++ ){
var conn = startMongodTest( 30000 + i , testName + "-config" + i );
this._alldbpaths.push( testName + "-config" + i )
this._configServers.push( conn );
}
@@ -183,6 +192,7 @@ ShardingTest = function( testName , numShards , verboseLevel , numMongos , other
else {
for ( var i=0; i<numShards; i++){
var conn = startMongodTest( 30000 + i , testName + i );
this._alldbpaths.push( testName +i )
this._connections.push( conn );
}
@@ -316,6 +326,11 @@ ShardingTest.prototype.stop = function(){
this._rs[i].test.stopSet( 15 );
}
}
if ( this._alldbpaths ){
for( i=0; i<this._alldbpaths.length; i++ ){
resetDbpath( "/data/db/" + this._alldbpaths[i] );
}
}
print('*** ' + this._testName + " completed successfully ***");
}
@@ -966,6 +981,8 @@ ReplSetTest = function( opts ){
this.name = opts.name || "testReplSet";
this.host = opts.host || getHostName();
this.numNodes = opts.nodes || 0;
this.useSeedList = opts.useSeedList || false;
this.bridged = opts.bridged || false;
this.ports = [];
@@ -1024,6 +1041,10 @@ ReplSetTest.prototype.getPort = function( n ){
ReplSetTest.prototype.getPath = function( n ){
var p = "/data/db/" + this.name + "-";
p += n.toString();
if ( ! this._alldbpaths )
this._alldbpaths = [ p ];
else
this._alldbpaths.push( p );
return p;
}
@@ -1326,9 +1347,15 @@ ReplSetTest.prototype.stop = function( n , signal ){
return stopMongod( port , signal || 15 );
}
ReplSetTest.prototype.stopSet = function( signal ) {
ReplSetTest.prototype.stopSet = function( signal , forRestart ) {
for(i=0; i < this.ports.length; i++) {
this.stop( i, signal );
}
if ( ! forRestart && this._alldbpaths ){
for( i=0; i<this._alldbpaths.length; i++ ){
resetDbpath( this._alldbpaths[i] );
}
}
print('*** Shut down repl set - test worked ****' )
}

View File

@@ -65,8 +65,7 @@ namespace mongo {
}
bool BackgroundJob::wait(int msMax, unsigned maxsleep) {
assert( state != NotStarted );
unsigned ms = 0;
unsigned ms = 1;
Date_t start = jsTime();
while ( state != Done ) {
sleepmillis(ms);
@@ -84,7 +83,7 @@ namespace mongo {
/* wait for several jobs to finish. */
void BackgroundJob::wait(list<BackgroundJob*>& L, unsigned maxsleep) {
unsigned ms = 0;
unsigned ms = 1;
{
x:
sleepmillis(ms);

View File

@@ -27,13 +27,13 @@ namespace mongo {
typedef boost::function<void()> lam;
/** typical usage is: task::fork( serverPtr ); */
/** typical usage is: task::fork( new Server("threadname") ); */
class Server : public Task {
public:
/** send a message to the port */
void send(lam);
Server(string name) : _name(name) { }
Server(string name) : _name(name), rq(false) { }
virtual ~Server() { }
/** send message but block until function completes */
@@ -42,9 +42,8 @@ namespace mongo {
void requeue() { rq = true; }
protected:
/* this needn't be abstract; i left it that way for now so i remember
to call Client::initThread() when using in mongo... */
virtual void starting() = 0;
/* REMINDER : for use in mongod, you will want to have this call Client::initThread(). */
virtual void starting() { }
private:
virtual bool initClient() { return true; }

View File

@@ -117,7 +117,6 @@ namespace mongo {
void Server::doWork() {
starting();
rq = false;
while( 1 ) {
lam f;
try {
@@ -134,7 +133,10 @@ namespace mongo {
f();
if( rq ) {
rq = false;
send(f);
{
boost::mutex::scoped_lock lk(m);
d.push_back(f);
}
}
} catch(std::exception& e) {
log() << "Server::doWork() exception " << e.what() << endl;
@@ -143,6 +145,27 @@ namespace mongo {
}
}
}
static Server *s;
static void abc(int i) {
cout << "Hello " << i << endl;
s->requeue();
}
class TaskUnitTest : public mongo::UnitTest {
public:
virtual void run() {
lam f = boost::bind(abc, 3);
//f();
s = new Server("unittest");
fork(s);
s->send(f);
sleepsecs(30);
cout <<" done" << endl;
}
}; // not running. taskunittest;
}
}

View File

@@ -74,6 +74,7 @@ namespace mongo {
string host() const { return _host; }
int port() const { return _port >= 0 ? _port : CmdLine::DefaultDBPort; }
bool hasPort() const { return _port >= 0; }
void setPort( int port ) { _port = port; }
private:

View File

@@ -158,15 +158,7 @@ namespace mongo {
static vector<Tee*> * globalTees;
public:
static void logLockless( const StringData& s ){
if ( doneSetup == 1717 ){
fwrite( s.data() , s.size() , 1 , logfile );
fflush( logfile );
}
else {
cout << s.data() << endl;
}
}
inline static void logLockless( const StringData& s );
static void setLogFile(FILE* f){
scoped_lock lk(mutex);
@@ -177,52 +169,9 @@ namespace mongo {
return 1717;
}
void flush(Tee *t = 0) {
// this ensures things are sane
if ( doneSetup == 1717 ) {
string msg = ss.str();
string threadName = getThreadName();
const char * type = logLevelToString(logLevel);
int spaceNeeded = msg.size() + 64 + threadName.size();
int bufSize = 128;
while ( bufSize < spaceNeeded )
bufSize += 128;
BufBuilder b(bufSize);
time_t_to_String( time(0) , b.grow(20) );
if (!threadName.empty()){
b.appendChar( '[' );
b.appendStr( threadName , false );
b.appendChar( ']' );
b.appendChar( ' ' );
}
if ( type[0] ){
b.appendStr( type , false );
b.appendStr( ": " , false );
}
b.appendStr( msg );
string out( b.buf() , b.len() - 1);
scoped_lock lk(mutex);
if( t ) t->write(logLevel,out);
if ( globalTees ){
for ( unsigned i=0; i<globalTees->size(); i++ )
(*globalTees)[i]->write(logLevel,out);
}
#ifndef _WIN32
//syslog( LOG_INFO , "%s" , cc );
#endif
fwrite(out.data(), out.size(), 1, logfile);
fflush(logfile);
}
_init();
}
inline void flush(Tee *t = 0);
Nullstream& setLogLevel(LogLevel l){
inline Nullstream& setLogLevel(LogLevel l){
logLevel = l;
return *this;
}
@@ -416,6 +365,69 @@ namespace mongo {
/** output the error # and error message with prefix.
handy for use as parm in uassert/massert.
*/
string errnoWithPrefix( const char * prefix = 0 );
string errnoWithPrefix( const char * prefix );
void Logstream::logLockless( const StringData& s ){
if ( doneSetup == 1717 ){
if(fwrite(s.data(), s.size(), 1, logfile)){
fflush(logfile);
}else{
int x = errno;
cout << "Failed to write to logfile: " << errnoWithDescription(x) << ": " << out << endl;
}
}
else {
cout << s.data() << endl;
}
}
void Logstream::flush(Tee *t) {
// this ensures things are sane
if ( doneSetup == 1717 ) {
string msg = ss.str();
string threadName = getThreadName();
const char * type = logLevelToString(logLevel);
int spaceNeeded = msg.size() + 64 + threadName.size();
int bufSize = 128;
while ( bufSize < spaceNeeded )
bufSize += 128;
BufBuilder b(bufSize);
time_t_to_String( time(0) , b.grow(20) );
if (!threadName.empty()){
b.appendChar( '[' );
b.appendStr( threadName , false );
b.appendChar( ']' );
b.appendChar( ' ' );
}
if ( type[0] ){
b.appendStr( type , false );
b.appendStr( ": " , false );
}
b.appendStr( msg );
string out( b.buf() , b.len() - 1);
scoped_lock lk(mutex);
if( t ) t->write(logLevel,out);
if ( globalTees ){
for ( unsigned i=0; i<globalTees->size(); i++ )
(*globalTees)[i]->write(logLevel,out);
}
#ifndef _WIN32
//syslog( LOG_INFO , "%s" , cc );
#endif
if(fwrite(out.data(), out.size(), 1, logfile)){
fflush(logfile);
}else{
int x = errno;
cout << "Failed to write to logfile: " << errnoWithDescription(x) << ": " << out << endl;
}
}
_init();
}
} // namespace mongo

View File

@@ -168,7 +168,11 @@ namespace mongo {
const int ret = select(maxfd+1, fds, NULL, NULL, &maxSelectTime);
if (ret == 0){
#if defined(__linux__)
_elapsedTime += ( 10000 - maxSelectTime.tv_usec ) / 1000;
#else
_elapsedTime += 10;
#endif
continue;
}
_elapsedTime += ret; // assume 1ms to grab connection. very rough

View File

@@ -14,7 +14,7 @@ namespace mongo {
// mongo processes version support
//
const char versionString[] = "1.5.9-pre-";
const char versionString[] = "1.6.1";
string mongodVersion() {
stringstream ss;