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

  

  

<强> Part1:写在最前
  

  

我们在使用MongoDB分片集群时,会使用如下命令来管理启停均衡器:
  

        祝辞sh.stopBalancer()停止均衡器   祝辞sh.startBalancer()开启均衡器      

<强>第二部分:背景
  

  

开启均衡器后,客户反馈前端应用写入缓慢,查询超时,因此我们尝试关闭均衡器,来避免块迁移对集群性能带来的影响。
  

  

但是在调用<代码> sh.stopBalancer>   

        mongos> sh.stopBalancer ()   等待活动主机…   等待均衡器锁……   断言。很快就失败了,味精:太长时间等待锁解锁均衡器   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   均衡器仍可能是活跃的,您必须手动验证使用的情况并非如此   配置。更新日志收集。   2018 - 02 - 11 - t16:28:29.753 + 0800   E查询(thread1)错误:错误:   断言。很快就失败了,味精:太长时间等待锁均衡器解锁:   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      

从上述报错能够看的出,是由于目前均衡器正在运行导致的,

  

3.4版在本中,均衡器运行在配置服务器的主节点上,在早期的版本中,均衡器是运行在蒙戈上的。当均衡器进程处于活动状态时,配置服务器副本集的主服务器通过修改配置数据库的锁集合中的文档,来获取“平衡器锁”。这个“平衡器锁”只能自己主动释放。

  

<强> Part3:排查方法
  

  

我们调用<代码> sh.status() 命令能够看到当前均衡器已经关闭了,但是运行还是是的,这说明有迁移正在运行只
  

        平衡器:   目前启用:不   当前运行:是的      

我们查看发现迁移集合下为空,说明没有集合在迁移
  

        mongos>db.migrations.find ()      

我们查看锁集合下的信息,处于2状态的说明正持有锁
  

        mongos>db.locks.find ()   {" _id ":“均衡器”,“状态”:2,“t”: ObjectId (“5 a324c42329457086086da07”),“人”:“ConfigServer:平衡器”,“过程”:“ConfigServer”、“当”:ISODate (“2018 - 01 - 31 t08:33:43.346z”),“为什么”:“csr均衡器”}      


  

  

锁集合中的为什么列告诉我们持有锁的原因,如果有正在迁移的文档,其状态应该是2,为什么中的原因会显示<代码>迁移块(s)在收集db.collationname>   

  

从3.4版本起,均衡器的状态字段将始终为值2,以防止老版本的蒙戈实例执行平衡操作。当字段指服务器配置成员成为主节点的时间。
  

  

  

<强> Part1:写在最前
  

  

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      

<强> Part3:原因分析
  

  

卡住的原因是由于客户端mongo是3.2版本,而配置节点是3.4版本,3.2版本的蒙戈在执行stopBalancer()时,stopBalancer代码假定如果balancerStop命令没有找的到,那么它会使用旧版本的逻辑,等待锁被释放,从3.4版本起,平衡进程从蒙戈移动之配置服务器的主要节点上。

  


  

  

通过这个案例,我们能够了解到mongo客户端版本带来的问题,以及有哪些常见原因导致sh.stopBalancer停不下来。由于笔者的水平有限,编写时间也很仓促,文中难免会出现一些错误或者不准确的地方,不妥之处恳请读者批评指正。

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