Skip to content

Commit 412aadd

Browse files
Merge pull request #138 from timvaillancourt/34_balancer_lock_fix_v2
Ensure we use a mongos connection for 3.4 balancer commands
2 parents c60178f + cc0731e commit 412aadd

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

mongodb_consistent_backup/Common/DB.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def connect(self):
4545
conn['admin'].command({"ping":1})
4646
except (ConnectionFailure, OperationFailure, ServerSelectionTimeoutError), e:
4747
logging.error("Unable to connect to %s! Error: %s" % (self.uri, e))
48-
raise OperationError(e)
48+
raise DBConnectionError(e)
4949
if conn is not None:
5050
self._conn = conn
5151
return self._conn

mongodb_consistent_backup/Sharding.py

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22

3+
from pymongo import DESCENDING
34
from time import sleep
45

56
from mongodb_consistent_backup.Common import DB, MongoUri, validate_hostname
@@ -18,6 +19,7 @@ def __init__(self, config, timer, db):
1819
self.timer_name = self.__class__.__name__
1920
self.config_server = None
2021
self.config_db = None
22+
self.mongos_db = None
2123
self._balancer_state_start = None
2224
self.restored = False
2325

@@ -36,31 +38,52 @@ def __init__(self, config, timer, db):
3638
def close(self):
3739
if self.config_db:
3840
self.config_db.close()
41+
if self.mongos_db:
42+
self.mongos_db.close()
3943
return self.restore_balancer_state()
4044

4145
def is_gte_34(self):
4246
return self.db.server_version() >= tuple("3.4.0".split("."))
4347

48+
def get_mongos(self, force=False):
49+
if not force and self.mongos_db:
50+
return self.mongos_db
51+
elif self.db.is_mongos():
52+
return self.db
53+
else:
54+
db = self.connection['config']
55+
for doc in db.mongos.find().sort('ping', DESCENDING):
56+
try:
57+
mongos_uri = MongoUri(doc['_id'])
58+
logging.debug("Found cluster mongos: %s" % mongos_uri)
59+
self.mongos_db = DB(mongos_uri, self.config, False, 'nearest')
60+
logging.info("Connected to cluster mongos: %s" % mongos_uri)
61+
return self.mongos_db
62+
except DBConnectionFailure, e:
63+
logging.debug("Failed to connect to mongos: %s, trying next available mongos" % mongos_uri)
64+
raise OperationError('Could not connect to any mongos!')
65+
4466
def get_start_state(self):
4567
self._balancer_state_start = self.get_balancer_state()
4668
logging.info("Began with balancer state running: %s" % str(self._balancer_state_start))
4769
return self._balancer_state_start
4870

4971
def shards(self):
5072
try:
51-
if self.is_gte_34():
73+
if self.db.is_configsvr() or not self.is_gte_34():
74+
return self.connection['config'].shards.find()
75+
elif self.is_gte_34():
5276
listShards = self.db.admin_command("listShards")
5377
if 'shards' in listShards:
5478
return listShards['shards']
55-
elif self.db.is_configsvr():
56-
return self.connection['config'].shards.find()
5779
except Exception, e:
5880
raise DBOperationError(e)
5981

6082
def check_balancer_running(self):
6183
try:
6284
if self.is_gte_34():
63-
balancerState = self.db.admin_command("balancerStatus")
85+
# 3.4+ configsvrs dont have balancerStatus, use self.get_mongos() to get a mongos connection for now
86+
balancerState = self.get_mongos().admin_command("balancerStatus")
6487
if 'inBalancerRound' in balancerState:
6588
return balancerState['inBalancerRound']
6689
else:
@@ -75,7 +98,8 @@ def check_balancer_running(self):
7598
def get_balancer_state(self):
7699
try:
77100
if self.is_gte_34():
78-
balancerState = self.db.admin_command("balancerStatus")
101+
# 3.4+ configsvrs dont have balancerStatus, use self.get_mongos() to get a mongos connection for now
102+
balancerState = self.get_mongos().admin_command("balancerStatus")
79103
if 'mode' in balancerState and balancerState['mode'] == 'off':
80104
return False
81105
return True
@@ -93,10 +117,11 @@ def get_balancer_state(self):
93117
def set_balancer(self, value):
94118
try:
95119
if self.is_gte_34():
120+
# 3.4+ configsvrs dont have balancerStart/Stop, even though they're the balancer! Use self.get_mongos() to get a mongos connection for now
96121
if value is True:
97-
self.db.admin_command("balancerStart")
122+
self.get_mongos().admin_command("balancerStart")
98123
else:
99-
self.db.admin_command("balancerStop")
124+
self.get_mongos().admin_command("balancerStop")
100125
else:
101126
if value is True:
102127
set_value = False

0 commit comments

Comments
 (0)