MongoDB诡异问题之sh.stopBalancer卡住的解决方法

  • A+
所属分类:MongoDB

配景

Part1:写在最前

我们在使用MongoDB sharding集群时,会使用如下敕令来治理启停Balancer:

>sh.stopBalancer() 结束Balancer
>sh.startBalancer() 开启Balancer

Part2:配景

开启balancer后,客户反馈前端利用写入迟缓,查询超时。是以我们测验考试封闭balancer,来避免chunk迁徙对集群机能带来的影响。

然则在挪用sh.stopBalancer的时刻,发现却停不下来,sh.stopBalancer会处于卡住的状况:

mongos>sh.stopBalancer()
Waiting for active hosts...
Waiting for the balancer lock...
assert.soon failed,msg:Waited too long for lock balancer to unlock
doassert@src/mongo/shell/assert.js:18:14
assert.soon@src/mongo/shell/assert.js:202:13
sh.waitForDLock@src/mongo/shell/utils_sh.js:198:1
sh.waitForBalancerOff@src/mongo/shell/utils_sh.js:264:9
sh.waitForBalancer@src/mongo/shell/utils_sh.js:294:9
sh.stopBalancer@src/mongo/shell/utils_sh.js:161:5
@(shell):1:1
Balancer still may be active, you must manually verify this is not the case using the
config.changelog collection.
2018-02-11T16:28:29.753+0800
E QUERY [thread1] Error: Error:
assert.soon failed, msg:Waited too long for lock balancer to unlock :
sh.waitForBalancerOff@src/mongo/shell/utils_sh.js:268:15
sh.waitForBalancer@src/mongo/shell/utils_sh.js:294:9
sh.stopBalancer@src/mongo/shell/utils_sh.js:161:5
@(shell):1:1

从上述报错可以或许看出,是因为今朝balancer正在运行导致的,

Warning:警告 在3.4版本中,balancer运行在config server 的主节点上,在早期的版本中,balancer是运行在mongos上的。 当balancer过程处于运动状况时,config server副本集的主服务器经由过程改动config数据库的lock聚拢中的文档,来获取“均衡器锁”。 这个“均衡器锁”只能本身自动开释。

Part3:排查办法

我们挪用sh.status()敕令可以或许看到当前balancer已经封闭了,然则running照样yes,这阐明有迁徙正在运行。 

 balancer:
Currently enabled: no
Currently running: yes

我们查看发现migrations聚拢下为空,阐明没有聚拢在迁徙

mongos> db.migrations.find()

我们查看locks聚拢下的信息,处于2状况的阐明正持有锁

mongos> db.locks.find()
{ "大众_id"大众 : "大众balancer"大众, "大众state"大众 : 2, "大众ts"大众 : ObjectId("大众5a324c42329457086086da07"大众), "大众who"大众 : "大众ConfigServer:Balancer"大众, "大众process"大众 : "大众ConfigServer"大众, "大众when"大众 : ISODate("大众2018-01-31T08:33:43.346Z"大众), "大众why"大众 : "大众CSRS Balancer"大众 }

Warning:警告

locks聚拢中的why列奉告我们持有锁的缘故原由,假如有正在迁徙的文档,其状况应该是2,why中的缘故原由会显示Migrating chunk(s) in collection db.collationname.

从3.4版本起,balancer的状况字段将始终为值2,以防止老版本的mongos实例执行均衡操作。 when字段指config server 成员成为主节点的光阴。

办理方法

Part1:写在最前

sh.stopBalancer停不下来,常见的可能缘故原由有以下几个:

正在做chunk迁徙,必需期待chunk迁徙完成后,能力够正常结束;
后真个server光阴分歧步;
mongo客户端版本低于server端,本文便是第3种环境。mongo客户真个版本是3.2版本,config server和mongod都是3.4版本的mongo。

Part2:办理方法

替换老版本的mongo客户端,使用3.4版本的客户端

mongos> sh.stopBalancer()
{ "大众ok"大众 : 1 }
 
config:PRIMARY> db.version()
3.4.9-2.9

Part3:缘故原由阐发

卡住的缘故原由是因为客户端mongo是3.2版本,而config节点是3.4版本,3.2版本的mongos在执行stopBalancer()时,stopBalancer代码假定假如balancerStop敕令没有找到,那么它会使用旧版本的逻辑,期待锁被开释。从3.4版本起,Balance过程从mongos移动之configer server的primary节点上。

总结

经由过程这个案例,我们可以或许相识到mongo客户端版本带来的问题,以及有哪些常见缘故原由导致sh.stopBalancer停不下来。因为笔者的程度有限,编写光阴也很仓皇,文中不免会呈现一些差错或者禁绝确的处所,不妥之处恳请读者批驳指正。

好了,以上便是这篇文章的全体内容了,愿望本文的内容对年夜家的进修或者事情具有必定的参考进修代价,假如有疑问年夜家可以留言交流,谢谢年夜家对剧本之家的支撑。

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: