diff options
Diffstat (limited to 'db/repl_block.cpp')
-rw-r--r-- | db/repl_block.cpp | 92 |
1 files changed, 52 insertions, 40 deletions
diff --git a/db/repl_block.cpp b/db/repl_block.cpp index 9cff24f..05be343 100644 --- a/db/repl_block.cpp +++ b/db/repl_block.cpp @@ -35,13 +35,13 @@ namespace mongo { class SlaveTracking : public BackgroundJob { public: - string name() { return "SlaveTracking"; } + string name() const { return "SlaveTracking"; } static const char * NS; struct Ident { - - Ident(BSONObj r,string h,string n){ + + Ident(BSONObj r,string h,string n) { BSONObjBuilder b; b.appendElements( r ); b.append( "host" , h ); @@ -52,18 +52,18 @@ namespace mongo { bool operator<( const Ident& other ) const { return obj.woCompare( other.obj ) < 0; } - + BSONObj obj; }; struct Info { - Info() : loc(0){} - ~Info(){ - if ( loc && owned ){ + Info() : loc(0) {} + ~Info() { + if ( loc && owned ) { delete loc; } } - bool owned; + bool owned; // true if loc is a pointer of our creation (and not a pointer into a MMF) OpTime * loc; }; @@ -72,33 +72,33 @@ namespace mongo { _started = false; } - void run(){ + void run() { Client::initThread( "slaveTracking" ); DBDirectClient db; - while ( ! inShutdown() ){ + while ( ! inShutdown() ) { sleepsecs( 1 ); if ( ! _dirty ) continue; - + writelock lk(NS); list< pair<BSONObj,BSONObj> > todo; - + { scoped_lock mylk(_mutex); - - for ( map<Ident,Info>::iterator i=_slaves.begin(); i!=_slaves.end(); i++ ){ + + for ( map<Ident,Info>::iterator i=_slaves.begin(); i!=_slaves.end(); i++ ) { BSONObjBuilder temp; temp.appendTimestamp( "syncedTo" , i->second.loc[0].asDate() ); - todo.push_back( pair<BSONObj,BSONObj>( i->first.obj.getOwned() , + todo.push_back( pair<BSONObj,BSONObj>( i->first.obj.getOwned() , BSON( "$set" << temp.obj() ).getOwned() ) ); } - + _slaves.clear(); } - for ( list< pair<BSONObj,BSONObj> >::iterator i=todo.begin(); i!=todo.end(); i++ ){ + for ( list< pair<BSONObj,BSONObj> >::iterator i=todo.begin(); i!=todo.end(); i++ ) { db.update( NS , i->first , i->second , true ); } @@ -106,52 +106,54 @@ namespace mongo { } } - void reset(){ + void reset() { scoped_lock mylk(_mutex); _slaves.clear(); } - void update( const BSONObj& rid , const string& host , const string& ns , OpTime last ){ + void update( const BSONObj& rid , const string& host , const string& ns , OpTime last ) { REPLDEBUG( host << " " << rid << " " << ns << " " << last ); scoped_lock mylk(_mutex); - + #ifdef _DEBUG MongoFileAllowWrites allowWrites; #endif Ident ident(rid,host,ns); Info& i = _slaves[ ident ]; - if ( i.loc ){ - i.loc[0] = last; + if ( i.loc ) { + if( i.owned ) + i.loc[0] = last; + else + getDur().setNoJournal(i.loc, &last, sizeof(last)); return; } - + dbMutex.assertAtLeastReadLocked(); BSONObj res; - if ( Helpers::findOne( NS , ident.obj , res ) ){ + if ( Helpers::findOne( NS , ident.obj , res ) ) { assert( res["syncedTo"].type() ); i.owned = false; i.loc = (OpTime*)res["syncedTo"].value(); - i.loc[0] = last; + getDur().setNoJournal(i.loc, &last, sizeof(last)); return; } - + i.owned = true; - i.loc = new OpTime[1]; - i.loc[0] = last; + i.loc = new OpTime(last); _dirty = true; - if ( ! _started ){ + if ( ! _started ) { // start background thread here since we definitely need it _started = true; go(); } } - - bool opReplicatedEnough( OpTime op , int w ){ + + bool opReplicatedEnough( OpTime op , int w ) { RARELY { REPLDEBUG( "looking for : " << op << " w=" << w ); } @@ -161,9 +163,9 @@ namespace mongo { w--; // now this is the # of slaves i need scoped_lock mylk(_mutex); - for ( map<Ident,Info>::iterator i=_slaves.begin(); i!=_slaves.end(); i++){ + for ( map<Ident,Info>::iterator i=_slaves.begin(); i!=_slaves.end(); i++) { OpTime s = *(i->second.loc); - if ( s < op ){ + if ( s < op ) { continue; } if ( --w == 0 ) @@ -171,9 +173,15 @@ namespace mongo { } return w <= 0; } - + + unsigned getSlaveCount() const { + scoped_lock mylk(_mutex); + + return _slaves.size(); + } + // need to be careful not to deadlock with this - mongo::mutex _mutex; + mutable mongo::mutex _mutex; map<Ident,Info> _slaves; bool _dirty; bool _started; @@ -182,12 +190,12 @@ namespace mongo { const char * SlaveTracking::NS = "local.slaves"; - void updateSlaveLocation( CurOp& curop, const char * ns , OpTime lastOp ){ + void updateSlaveLocation( CurOp& curop, const char * ns , OpTime lastOp ) { if ( lastOp.isNull() ) return; - + assert( str::startsWith(ns, "local.oplog.") ); - + Client * c = curop.getClient(); assert(c); BSONObj rid = c->getRemoteID(); @@ -197,11 +205,15 @@ namespace mongo { slaveTracking.update( rid , curop.getRemoteString( false ) , ns , lastOp ); } - bool opReplicatedEnough( OpTime op , int w ){ + bool opReplicatedEnough( OpTime op , int w ) { return slaveTracking.opReplicatedEnough( op , w ); } - void resetSlaveCache(){ + void resetSlaveCache() { slaveTracking.reset(); } + + unsigned getSlaveCount() { + return slaveTracking.getSlaveCount(); + } } |