Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions mongodb_consistent_backup/Replication/Replset.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ def get_rs_quorum(self):
electable_members = len(self.get_electable_members())
return ceil(electable_members / 2.0)

def is_member_electable(self, member):
for electable_member in self.get_electable_members():
if member == electable_member:
return True
return False

def find_primary(self, force=False, quiet=False):
if force or not self.primary:
rs_status = self.get_rs_status(force, quiet)
Expand Down Expand Up @@ -166,19 +172,23 @@ def find_secondary(self, force=False, quiet=False):
if self.secondary and not force:
return self.secondary

secondary_count = 0
electable_count = 0
for member in rs_status['members']:
member_uri = MongoUri(member['name'], 27017, rs_name)
member_uri = MongoUri(member['name'], 27017, rs_name)
member_config = self.get_rs_config_member(member)

if self.is_member_electable(member_config):
electable_count += 1

if member['state'] == 7:
logging.info("Found ARBITER %s, skipping" % member_uri)
elif member['state'] > 2:
logging.warning("Found down or unhealthy SECONDARY %s with state: %s" % (member_uri, member['stateStr']))
elif member['state'] == 2 and member['health'] > 0:
log_data = {}
score = self.max_lag_secs * 10
score_scale = 100 / score
priority = 0
member_config = self.get_rs_config_member(member)
log_data = {}
score = self.max_lag_secs * 10
score_scale = 100 / score
priority = 0
if 'hidden' in member_config and member_config['hidden']:
score += (score * self.hidden_weight)
log_data['hidden'] = True
Expand Down Expand Up @@ -207,7 +217,6 @@ def find_secondary(self, force=False, quiet=False):
'score': score
}
log_msg = "Found SECONDARY %s" % member_uri
secondary_count += 1
else:
log_msg = "Found SECONDARY %s with too high replication lag! Skipping" % member_uri

Expand All @@ -219,10 +228,10 @@ def find_secondary(self, force=False, quiet=False):
log_data['score'] = int(score)
logging.info("%s: %s" % (log_msg, str(log_data)))
self.replset_summary['secondary'] = { "member": member, "uri": member_uri.str(), "data": log_data }
if self.secondary is None or (secondary_count + 1) < quorum:
logging.error("Not enough valid secondaries in replset %s to take backup! Num replset members: %i, required quorum: %i" % (
if self.secondary is None or electable_count < quorum:
logging.error("Not enough valid secondaries in replset %s to take backup! Num replset electable members: %i, required quorum: %i" % (
rs_name,
secondary_count,
electable_count,
quorum
))
raise OperationError("Not enough secondaries in replset %s to safely take backup!" % rs_name)
Expand Down