MongoDB诡异问题:sh.stopBalancer卡住

26次阅读
没有评论

共计 2596 个字符,预计需要花费 7 分钟才能阅读完成。

自动写代码机器人,免费开通
MongoDB 诡异问题:sh.stopBalancer 卡住MongoDB 诡异问题:sh.stopBalancer 卡住

背景

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 停不下来。由于笔者的水平有限,编写时间也很仓促,文中难免会出现一些错误或者不准确的地方,不妥之处恳请读者批评指正。喜欢笔者的文章,右上角点一波关注,谢谢~

MongoDB 诡异问题:sh.stopBalancer 卡住

MongoDB 诡异问题:sh.stopBalancer 卡住

向 AI 问一下细节

丸趣 TV 网 – 提供最优质的资源集合!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-12-18发表,共计2596字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)