【问题】
最近发现3.4版本mongo集群实例日志发现疯狂刷如下日志:
I SHARDING [RangeDeleter] waiting for open cursors before removing range [{_id: -8961469181018981374 }, { _id: -8961075440282168396 }) in test.expInfos, elapsed secs: 19048578, cursor ids: [100968947595]
通过日志大概得出如下线索:
1、chunk迁移完成后,移除集合expInfos中一段范围_id时,被当前打开游标阻塞(迁移chunk与删除相关记录是异步操作,也可以通过修改变成同步方式).
2、这个RangeDeleter这个操作被阻塞220天,通常mongo里面cursor只要没有设置非超时参数,基本上都会自动被回收。
3、给出cursor id:100968947595,但没有找到对应语句。
【查找执行语句】
通过如下语句并没有找到相关执行语句,所以也没有办法知道谁干了什么阻塞,只能killcursor.
{{ db.currentOp().inprog.map(function (o) { if (o.ns == "admin.$cmd") return { opid: o.opid, secs: o.secs_running, ns: o.ns, command: o.command }}).filter(Boolean)}}
【处理方案】
备注:执行如下命令后,后台日志错误消失。
use test;
db.runCommand({"killCursors": "expInfos", "cursors": [ 100968947595 ] } )
【官方解释】
3.4版本实例日志会打印出来阻塞游标ID信息,但3.6,4.0日志不会显示,从4.2版本可以通过listCursors命令来打印出来,对于3.6,4.0版本只能通过重启应用或者主从角色切换来解决这个问题.
4.2版本可以通过这个命令 db.runCommand("listCursors")
【建议】
1、不建议是no timeout的cursor,因为这个需要手动关闭cursor,否则造成服务器cursor空间不释放.造成资源紧张。
2、建议使用带timeout的cursor.