mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 09:06:21 +01:00
rs
This commit is contained in:
parent
ca9e079e22
commit
803c4e1514
@ -64,7 +64,7 @@ namespace mongo {
|
||||
|
||||
static const int VETO = -10000;
|
||||
|
||||
bool ReplSet::Consensus::electSelf() {
|
||||
void ReplSet::Consensus::_electSelf() {
|
||||
ReplSet::Member& me = *rs._self;
|
||||
electCmd = BSON(
|
||||
"replSetElect" << 1 <<
|
||||
@ -96,11 +96,26 @@ namespace mongo {
|
||||
if( time(0) - start > 30 ) {
|
||||
// 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -53,51 +53,51 @@ namespace mongo {
|
||||
/** called as the health threads get new results */
|
||||
void ReplSet::Manager::checkNewState() {
|
||||
static mutex m;
|
||||
scoped_lock lk(m);
|
||||
{
|
||||
scoped_lock lk(m);
|
||||
|
||||
//log() << "replSet checkNewState " << rsLog;
|
||||
|
||||
const Member *p = _rs->currentPrimary();
|
||||
const Member *p2 = findOtherPrimary();
|
||||
try { p2 = findOtherPrimary(); }
|
||||
catch(string s) {
|
||||
log() << "replSet warning DIAG TODO " << s << rsLog;
|
||||
return;
|
||||
}
|
||||
|
||||
if( p == p2 && p ) return;
|
||||
|
||||
if( p2 ) {
|
||||
/* someone else thinks they are primary. */
|
||||
if( p == p2 )
|
||||
const Member *p = _rs->currentPrimary();
|
||||
const Member *p2 = findOtherPrimary();
|
||||
try { p2 = findOtherPrimary(); }
|
||||
catch(string s) {
|
||||
/* two other nodes think they are primary (asynchronously polled) -- wait for things to settle down. */
|
||||
log() << "replSet warning DIAG TODO " << s << rsLog;
|
||||
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 ) {
|
||||
/* we are already primary, and nothing significant out there has changed. */\
|
||||
/* todo: if !aMajoritySeemsToBeUp, relinquish */
|
||||
assert( p == _rs->_self );
|
||||
return;
|
||||
}
|
||||
if( p == p2 && p ) 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;
|
||||
}
|
||||
if( p2 ) {
|
||||
/* someone else thinks they are primary. */
|
||||
if( p == p2 ) // already match
|
||||
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;
|
||||
_rs->_self->_lastHeartbeatErrMsg.set("todo code #2");
|
||||
if( p ) {
|
||||
/* 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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -54,7 +54,6 @@ namespace mongo {
|
||||
State _myState;
|
||||
|
||||
public:
|
||||
|
||||
void fatal();
|
||||
bool isMaster(const char *client);
|
||||
void fillIsMaster(BSONObjBuilder&);
|
||||
@ -66,8 +65,7 @@ namespace mongo {
|
||||
replsetname/host1,host2:port,...
|
||||
where :port is optional.
|
||||
|
||||
throws exception if a problem initializing.
|
||||
*/
|
||||
throws exception if a problem initializing. */
|
||||
ReplSet(string cfgString);
|
||||
|
||||
/* call after constructing to start - returns fairly quickly after launching its threads */
|
||||
@ -90,12 +88,15 @@ namespace mongo {
|
||||
void loadConfig();
|
||||
void initFromConfig(ReplSetConfig& c);//, bool save);
|
||||
|
||||
struct Consensus {
|
||||
class Consensus {
|
||||
ReplSet &rs;
|
||||
Consensus(ReplSet *t) : rs(*t) { }
|
||||
bool inprog;
|
||||
void _electSelf();
|
||||
public:
|
||||
Consensus(ReplSet *t) : rs(*t),inprog(false) { }
|
||||
int totalVotes() const;
|
||||
bool aMajoritySeemsToBeUp() const;
|
||||
bool electSelf();
|
||||
void electSelf();
|
||||
} elect;
|
||||
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user