MongoDB诡异问题:sh。stopBalancer卡住
背景
我们在使用MongoDB分片集群时,会使用如下命令来管理启停均衡器:
祝辞sh.stopBalancer(),,停止均衡器 祝辞sh.startBalancer(),开启均衡器
开启均衡器后,客户反馈前端应用写入缓慢,查询超时,因此我们尝试关闭均衡器,来避免块迁移对集群性能带来的影响。
但是在调用sh.stopBalancer的时候,发现却停不下来,sh。stopBalancer会处于卡住的状态:
mongos> sh.stopBalancer () Waiting for  active 主机… Waiting for 从而,balancer 锁…… assert.soon 失败了,味精:Waited too  long for lock balancer 用解锁 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 @(壳):1:1 Balancer still  may be 活跃,,你must manually verify 却;能够is not 从而case using config.changelog 收集。 2018 - 02 - 11 - t16:28:29.753 + 0800 E QUERY ,,, (thread1),错误:,错误: assert.soon 失败了,,味精:Waited too long for lock balancer 用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 @(壳):1:1
从上述报错能够看的出,是由于目前均衡器正在运行导致的,
强> 强> <强> <强> 强> 强>在
<>之前我们调用sh.status()命令能够看到当前均衡器已经关闭了,但是运行还是是的,这说明有迁移正在运行又是; 平衡器才能: Currently 启用:没有 Currently 运行:是的 , 我们查看发现迁移集合下为空,说明没有集合在迁移 mongos>, db.migrations.find () 我们查看锁集合下的信息,处于2状态的说明正持有锁 mongos>, db.locks.find () {,“_id",:,“balancer",,“state",,, 2,,“ts",:, ObjectId (“5 a324c42329457086086da07"),“who",:,“ConfigServer: balancer",,“process",:,“ConfigServer",,“when",:, ISODate (“2018 - 01 - 31 t08:33:43.346z"),,“why",:,“CSRS balancer",}
<强> <强> 强> 强> <强> <强> 强> 强>,
锁集合中的为什么列告诉我们持有锁的原因,如果有正在迁移的文档,其状态应该是2,为什么中的原因会显示迁移块(s)在收集db.collationname。
从3.4版本起,均衡器的状态字段将始终为值2,以防止老版本的蒙戈实例执行平衡操作。当字段指服务器配置成员成为主节点的时间。
解决办法
sh。stopBalancer停不下来,常见的可能原因有以下几个:
- <李>
正在做块迁移,必须等待块迁移完成后,才能够正常停止;
李> <李>后端服务器的时间不同步;
李> <李>mongo客户端版本低于服务器端,本文就是第3种情况.mongo客户端的版本是3.2版本,配置服务器和mongod都是3.4版本的mongo。
李>
强>
替换老版本的mongo客户端,使用3.4版本的客户端
mongos>, sh.stopBalancer () {,“ok",:, 1,} , 配置:PRIMARY>, db.version () 3.4.9-2.9
<强> 强>
<强> 强>
卡住的原因是由于客户端mongo是3.2版本,而配置节点是3.4版本,3.2版本的蒙戈在执行stopBalancer()时,stopBalancer代码假定如果balancerStop命令没有找的到,那么它会使用旧版本的逻辑,等待锁被释放,从3.4版本起,平衡进程从蒙戈移动之配置服务器的主要节点上。
<强> 强>
<强>通过这个案例,我们能够了解到mongo客户端版本带来的问题,以及有哪些常见原因导致sh。stopBalancer停不下来。由于笔者的水平有限,编写时间也很仓促,文中难免会出现一些错误或者不准确的地方,不妥之处恳请读者批评指正。喜欢笔者的文章,右上角点一波关注,谢谢~ 强>