diff --git a/db/db.cpp b/db/db.cpp index 8a883a6c9ef..5dd95418dc8 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -37,6 +37,7 @@ namespace mongo { extern int port; extern int curOp; + extern bool autoresync; extern string dashDashSource; extern int opLogging; extern long long oplogSize; @@ -449,6 +450,8 @@ int main(int argc, char* argv[], char *envp[] ) master = true; else if ( s == "--slave" ) slave = true; + else if ( s == "--autoresync" ) + autoresync = true; else if ( s == "--help" || s == "-?" || s == "--?" ) goto usage; else if ( s == "--quiet" ) @@ -459,10 +462,10 @@ int main(int argc, char* argv[], char *envp[] ) noauth = true; else if ( s == "--auth" ) noauth = false; - else if( s == "--sysinfo" ) { - sysInfo(); - return 0; - } + else if( s == "--sysinfo" ) { + sysInfo(); + return 0; + } else if ( s == "--verbose" ) logLevel = 1; else if ( s.find( "-v" ) == 0 ){ @@ -486,7 +489,7 @@ int main(int argc, char* argv[], char *envp[] ) appsrvPath = argv[++i]; else if ( s == "--nocursors" ) useCursors = false; - else if ( strncmp(s.c_str(), "--oplogSize", 11) == 0 ) { + else if ( s == "--oplogSize" ) { long x = strtol( argv[ ++i ], 0, 10 ); uassert("bad arg", x > 0); oplogSize = x * 1024 * 1024; @@ -543,6 +546,7 @@ usage: out() << " --slave" << endl; out() << " --source " << endl; out() << " --pairwith " << endl; + out() << " --autoresync" << endl; out() << endl; return 0; diff --git a/db/instance.cpp b/db/instance.cpp index 60b77ec5f11..98c5f68c57e 100644 --- a/db/instance.cpp +++ b/db/instance.cpp @@ -39,7 +39,8 @@ namespace mongo { bool slave = false; bool master = false; // true means keep an op log extern int curOp; - + bool autoresync = false; + boost::mutex &dbMutex( *(new boost::mutex) ); MutexInfo dbMutexInfo; //int dbLocked = 0; diff --git a/db/repl.cpp b/db/repl.cpp index 95d9cadaca1..07407571e22 100644 --- a/db/repl.cpp +++ b/db/repl.cpp @@ -68,6 +68,9 @@ namespace mongo { */ const char *allDead = 0; + extern bool autoresync; + time_t lastForcedResync = 0; + } // namespace mongo #include "replset.h" @@ -201,14 +204,9 @@ namespace mongo { errmsg = "not dead, no need to resync"; return false; } - vector sources; - ReplSource::loadAll(sources); - for( vector< ReplSource * >::iterator i = sources.begin(); i != sources.end(); ++i ) { - (*i)->userResync(); - } - allDead = 0; + ReplSource::forceResyncDead( "user" ); result.append( "info", "triggered resync for all sources" ); - return true; + return true; } } cmdResync; @@ -573,9 +571,29 @@ namespace mongo { BSONObj opTimeQuery = fromjson("{\"getoptime\":1}"); - void ReplSource::userResync() { + bool ReplSource::throttledForceResyncDead( const char *requester ) { + if ( time( 0 ) - lastForcedResync > 600 ) { + forceResyncDead( requester ); + lastForcedResync = time( 0 ); + return true; + } + return false; + } + + void ReplSource::forceResyncDead( const char *requester ) { + if ( !allDead ) + return; + vector sources; + ReplSource::loadAll(sources); + for( vector< ReplSource * >::iterator i = sources.begin(); i != sources.end(); ++i ) { + (*i)->forceResync( requester ); + } + allDead = 0; + } + + void ReplSource::forceResync( const char *requester ) { for( set< string >::iterator i = dbs.begin(); i != dbs.end(); ++i ) { - log() << "user resync: dropping database " << *i << endl; + log() << requester << " resync: dropping database " << *i << endl; string dummyns = *i + "."; setClientTempNs( dummyns.c_str() ); assert( database->name == *i ); @@ -1141,8 +1159,10 @@ namespace mongo { int s = 0; { dblock lk; - if ( allDead ) - break; + if ( allDead ) { + if ( !autoresync || !ReplSource::throttledForceResyncDead( "auto" ) ) + break; + } assert( syncing == 0 ); syncing++; } diff --git a/db/repl.h b/db/repl.h index 3185db1071a..c2c6f8d2f65 100644 --- a/db/repl.h +++ b/db/repl.h @@ -36,7 +36,7 @@ namespace mongo { class DBClientCursor; extern bool slave; extern bool master; - + bool cloneFrom(const char *masterHost, string& errmsg, const string& fromdb, bool logForReplication, bool slaveOk, bool useReplAuth); @@ -176,8 +176,9 @@ namespace mongo { return !addDbNextPass.empty(); } - // Trigger a resync, at user's request. - void userResync(); + static bool throttledForceResyncDead( const char *requester ); + static void forceResyncDead( const char *requester ); + void forceResync( const char *requester ); }; /* Write operation to the log (local.oplog.$main)