首页 存档 技术 查看内容

MongoDB管理:使用killOp干掉LongRunningOperation MongoDB 管理:使用 killOp 干掉 L ...

2018-3-30 13:00 |来自: 互联网 384 0

摘要: MongoDB 管理:使用 killOp 干掉 Long Running Operation MongoDB 提供了 killOp 请求,用于干掉运行时间很长的请求,killOp 通常需要与 currentOp 组合起来使用;先根据 currentOp 查询到请求的 opid,然后根据 opi ...

MongoDB 管理:使用 killOp 干掉 Long Running Operation

MongoDB 提供了 killOp 请求,用于干掉运行时间很长的请求,killOp 通常需要与 currentOp 组合起来使用;先根据 currentOp 查询到请求的 opid,然后根据 opid 发送 killOp 的请求。




currentOp


currentOp 的使用,参考官方文档


currentOp 会将后端 Mongod 上正在执行的请求都列出来,也可根据查询条件(如请求类型,请求是否正在等待锁,请求操作的 DB 或 collection)来进行过滤。


例 1:查询所有正在等待锁的写操作

db.currentOp(
  {
   "waitingForLock" : true,
   $or: [
    { "op" : { "$in" : [ "insert", "update", "remove" ] } },
    { "query.findandmodify": { $exists: true } }
  ]
  }
)



例 2:查询所有操作db1并且执行时间已超过3s的请求

db.currentOp(
  {
   "active" : true,
   "secs_running" : { "$gt" : 3 },
   "ns" : /^db1\./
  }
)


currentOp 的过滤条件包括

  1. 请求操作类型,insert、update、delete...

  2. 请求对应的 connectionId,threadId

  3. 请求是否正在等待锁

  4. 请求执行时间

  5. 请求操作的 DB 或 collection

  6. 请求 query 的内容

  7. ...

killOp


currentOp 的输出结果里,每个请求包含一个 opid 字段,有了 opid,就可以发送 killOp 来干掉对应的请求。

db.killOp(opid)


要了解 killOp 的意义,需要先搞清楚几个问题


客户端到 Monogd Server 连接断掉后,连接上执行的请求是否会立即结束?


比如你通过 mongo shell,发送了一个 createIndex 的请求,给某个包含 1000w 个文档的集合建立索引,这个请求会耗时很久,你想提前中止请求,Ctrl-C 停掉了 mongo shell,此时 mongo shell 到 server 的连接会关闭掉。


但后端 createIndex 的请求(MongoDB 每个连接的请求由一个对应的线程来处理)不会立即结束,而是会一直执行下去,直到 createIndex 结束,给客户端发送应答时,发现连接已经关闭,然后线程才退出。


为了让 createIndex 早点结束,你就需要 killOp 来帮忙,通过 currentOp 找到 craeteIndex 请求的 opid,然后发送 killOp,createIndex 会在下个『检查点』就结束执行,整个线程退出。



发送 killOp 后,请求是否会立即结束?


killOp 的实现原理如下


每个连接对应的服务线程存储了一个 killPending 的字段,当发送 killOp 时,会将该字段置 1;请求在执行过程中,可以通过不断的调用 OperationContext::checkForInterrupt() 来检查 killPending 是否被设置,如果被设置,则线程退出。


一个请求要支持 killOp,必须在请求的处理逻辑里加上 checkForInterrupt() 检查点才行,否则即使发送了 killOp,也只能等待请求完全处理完毕线程才会退出。


比如 createIndex 的处理逻辑里包含了类似如下的代码,在 createIndex 的循环过程中,一旦 killPending 被置 1 了,createIndex 的执行可以在当前循环结束时退出。

while (!createIndexFinished) {
  createIndexForOneElement();
  checkForInterupt();
}


所以发送 killOp 后,请求要执行到下一个『检查点』线程才会退出,MongoDB 在很多可能耗时长的请求中,都加入了 checkForInterrupt() 检查点,如创建索引,repair database,mapreduce、aggregation 等。

http://blog.yunnotes.net/index.php/kill-long-running-operation/

sohu-dba

本文转载自:微信公众账号 - SOHU-DBA,版权归原作者所有!

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部