0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
This commit is contained in:
Dwight Merriman 2010-05-15 18:20:55 -04:00
parent ca9e079e22
commit 803c4e1514
3 changed files with 66 additions and 50 deletions

View File

@ -64,7 +64,7 @@ namespace mongo {
static const int VETO = -10000; static const int VETO = -10000;
bool ReplSet::Consensus::electSelf() { void ReplSet::Consensus::_electSelf() {
ReplSet::Member& me = *rs._self; ReplSet::Member& me = *rs._self;
electCmd = BSON( electCmd = BSON(
"replSetElect" << 1 << "replSetElect" << 1 <<
@ -96,11 +96,26 @@ namespace mongo {
if( time(0) - start > 30 ) { if( time(0) - start > 30 ) {
// defensive; should never happen as we have timeouts on connection and operation for our conn // defensive; should never happen as we have timeouts on connection and operation for our conn
log() << "replSet too much time passed during election, ignoring result" << rsLog; log() << "replSet too much time passed during election, ignoring result" << rsLog;
return false;
} }
return true; /* succeeded. */
rs._myState = PRIMARY;
log() << "replSet elected self as primary" << rsLog;
return;
} }
return false; }
void ReplSet::Consensus::electSelf() {
static mutex m;
{
scoped_lock lk(m);
if( inprog ) return;
inprog = true;
}
try { _electSelf(); } catch(...) { }
{
scoped_lock lk(m);
inprog = false;
}
} }
} }

View File

@ -53,51 +53,51 @@ namespace mongo {
/** called as the health threads get new results */ /** called as the health threads get new results */
void ReplSet::Manager::checkNewState() { void ReplSet::Manager::checkNewState() {
static mutex m; static mutex m;
scoped_lock lk(m); {
scoped_lock lk(m);
//log() << "replSet checkNewState " << rsLog; const Member *p = _rs->currentPrimary();
const Member *p2 = findOtherPrimary();
const Member *p = _rs->currentPrimary(); try { p2 = findOtherPrimary(); }
const Member *p2 = findOtherPrimary(); catch(string s) {
try { p2 = findOtherPrimary(); } /* two other nodes think they are primary (asynchronously polled) -- wait for things to settle down. */
catch(string s) { log() << "replSet warning DIAG TODO " << s << rsLog;
log() << "replSet warning DIAG TODO " << s << rsLog;
return;
}
if( p == p2 && p ) return;
if( p2 ) {
/* someone else thinks they are primary. */
if( p == p2 )
return; return;
if( p == 0 ) }
noteARemoteIsPrimary(p2); return;
if( p != _rs->_self )
noteARemoteIsPrimary(p2); return;
/* we thought we were primary, yet now someone else thinks they are. */
if( !_rs->elect.aMajoritySeemsToBeUp() )
noteARemoteIsPrimary(p2); return;
/* ignore for now, keep thinking we are master */
return;
}
if( p ) { if( p == p2 && p ) return;
/* we are already primary, and nothing significant out there has changed. */\
/* todo: if !aMajoritySeemsToBeUp, relinquish */
assert( p == _rs->_self );
return;
}
/* no one seems to be primary. shall we try to elect ourself? */ if( p2 ) {
if( !_rs->elect.aMajoritySeemsToBeUp() ) { /* someone else thinks they are primary. */
_rs->_self->_lastHeartbeatErrMsg.set("can't see a majority, won't elect self"); if( p == p2 ) // already match
return; return;
} if( p == 0 )
noteARemoteIsPrimary(p2); return;
if( p != _rs->_self )
noteARemoteIsPrimary(p2); return;
/* we thought we were primary, yet now someone else thinks they are. */
if( !_rs->elect.aMajoritySeemsToBeUp() )
noteARemoteIsPrimary(p2); return;
/* ignore for now, keep thinking we are master */
return;
}
log() << "replSet todo elect self as primary primary" << rsLog; if( p ) {
_rs->_self->_lastHeartbeatErrMsg.set("todo code #2"); /* we are already primary, and nothing significant out there has changed. */
/* todo: if !aMajoritySeemsToBeUp, relinquish */
assert( p == _rs->_self );
return;
}
/* no one seems to be primary. shall we try to elect ourself? */
if( !_rs->elect.aMajoritySeemsToBeUp() ) {
_rs->_self->_lastHeartbeatErrMsg.set("can't see a majority, won't elect self");
return;
}
_rs->_self->_lastHeartbeatErrMsg.set("");
}
_rs->elect.electSelf();
} }
} }

View File

@ -54,7 +54,6 @@ namespace mongo {
State _myState; State _myState;
public: public:
void fatal(); void fatal();
bool isMaster(const char *client); bool isMaster(const char *client);
void fillIsMaster(BSONObjBuilder&); void fillIsMaster(BSONObjBuilder&);
@ -66,8 +65,7 @@ namespace mongo {
replsetname/host1,host2:port,... replsetname/host1,host2:port,...
where :port is optional. where :port is optional.
throws exception if a problem initializing. throws exception if a problem initializing. */
*/
ReplSet(string cfgString); ReplSet(string cfgString);
/* call after constructing to start - returns fairly quickly after launching its threads */ /* call after constructing to start - returns fairly quickly after launching its threads */
@ -90,12 +88,15 @@ namespace mongo {
void loadConfig(); void loadConfig();
void initFromConfig(ReplSetConfig& c);//, bool save); void initFromConfig(ReplSetConfig& c);//, bool save);
struct Consensus { class Consensus {
ReplSet &rs; ReplSet &rs;
Consensus(ReplSet *t) : rs(*t) { } bool inprog;
void _electSelf();
public:
Consensus(ReplSet *t) : rs(*t),inprog(false) { }
int totalVotes() const; int totalVotes() const;
bool aMajoritySeemsToBeUp() const; bool aMajoritySeemsToBeUp() const;
bool electSelf(); void electSelf();
} elect; } elect;
public: public: