如何使用killOp杀死Mongo中的长时间运行操作
详细解释:
currentOp()详细解释
{
"inprog" : [
{
“opid”:6222,
“活动”:true,
“secs_running”: 3、
"microsecs_running": NumberLong(3662328),
"微秒s_running" nbsp;"ns" : "local.oplog.rs",
“查询”:{
"threadId" : "0x7f1370cb4700",
"connectionId" : 5,
"waitingForLock" : false,< br/>< /p>
“numYields”:0,
“lockStats”:{
“timeLockedMicros”:{
p>
"r" : NumberLong(141),
"w" : NumberLong(0)
},
"timeAcquiringMicros": {
"r" : NumberLong(16),
"w" : NumberLong(0 )
> }
}
}
}
"opid": 6222,#进程号
"active" : true,#是否处于活动状态
"secs_running" : 3,#操作已经运行了多少秒
p>
"op" : "getmore",#操作类型,包括(insert/query/update/remove/getmore/command)
"ns" : "local.oplog .rs",#命名空间
"query" : {},#如果op是查询操作,则查询内容将显示在这里;还说具体的操作语句体
"client" : "192.168.91.132:45745",#连接的客户端信息
"desc" : "conn5",#数据库连接信息
"threadId" : "0x7f1370cb4700",#线程ID
< /p>< p>"connectionId" : 5,#数据库的连接ID
"waitingForLock" : false,#是否等待获取锁
"numYields" : 0,
"lockStats" : {
"timeLockedMicros" : {#锁定时间以微秒为单位< br/>
"r" : NumberLong(141),#整个MongoDB实例的全局读锁
"w" : NumberLong(0)},#整个 MongoDB 实例的全局写锁
"timeAcquiringMicros" : {#获取锁需要等待的微秒
"r" : NumberLong(16),#整个MongoDB实例全局读锁
"w" : NumberLong(0)}#整个MongoDB实例全局写锁
< br/>
MongoDB提供了killOp 请求用于终止需要很长时间运行的请求。 KillOp通常需要与currentOp结合使用;首先根据currentOp查询请求的opid,然后根据opid发送killOp请求。
currentOp
currentOp的使用可以参考官方文档
currentOp会列出后端Mongod上正在执行的所有请求,也可以根据查询条件(如请求类型、请求是否正在等待锁、请求操作的DB还是集合)进行过滤。
示例一:查询所有正在等待锁的写操作
db.currentOp( { "waitingForLock" : true, $or: [ "op" : { "$in" : [ "insert", "update", "remove" ] } }, { "query.findandmodify": { $exists: true } } ] )
示例2:查询db1所有操作并执行请求耗时超过 3 秒
db.currentOp( { "active" : true, "secs_running" : { "$gt" : 3 }, "ns" : /^db1\./ })
currentOp的过滤条件包括
请求操作类型,插入、更新、删除...
对应的connectionId请求,threadId
请求是否正在等待锁
请求执行时间
请求操作的DB或集合
请求的查询内容
…
killOp
在currentOp的输出中,每个请求都包含一个opid字段。有了opid,就可以发送killOp来杀死相应的请求。
db.killOp(opid)
要理解killOp的含义,首先需要理解几个问题
客户端与Monogd建立连接后服务器断开连接,连接上执行的请求会立即结束吗?
例如,您通过 mongo shell 发送 createIndex 请求来索引包含 1000 万个文档的集合。这个请求将需要很长时间。如果你想提前中止请求,Ctrl-C阻止它。安装 mongo shell 后,mongo shell 到服务器的连接将被关闭。
但是后端createIndex请求(每个MongoDB连接请求都由相应的线程处理)不会立即结束,而是会继续执行,直到createIndex结束并向客户端发送响应。 ,发现连接已经关闭,然后线程就退出了。
为了让createIndex提前结束,需要killOp来帮忙。通过currentOp找到craeteIndex请求的opid,然后发送killOp。 CreateIndex将在下一个“检查点”结束执行,整个线程将退出。
发送killOp后,请求会立即结束吗?
killOp的实现原理如下
每个连接对应的服务线程都会存储一个killPending字段。当发送killOp时,该字段将被设置为1;请求正在执行过程中,可以查看是否有killPending通过连续调用OperationContext::checkForInterrupt()来设置。如果已设置,则线程退出。
对于支持killOp的请求,必须在请求处理逻辑中添加checkForInterrupt()检查点。否则,即使发送了killOp,也只能等待请求被完全处理。线程只有在完成后才会退出。
例如createIndex的处理逻辑包含类似下面的代码。在createIndex的循环过程中,一旦killPending设置为1,createIndex的执行就可以在当前循环结束时退出。
while (!createIndexFinished) { createIndexForOneElement(); checkForInterupt();}
所以发送killOp后,请求直到下一个“检查点”线程才会退出,MongoDB的CheckForInterrupt()检查点被添加到很多可能需要很长时间的请求上,比如创建索引、修复数据库、mapreduce、聚合等。
感谢您的回复阿丁!这篇关于《如何使用killOp杀死Mongo中长时间运行的操作》的文章就分享到这里。希望以上内容能够给大家带来一些帮助,让大家学到更多的知识。如果您觉得文章不错,可以分享一下。走出去,让更多人看到!
2. 本站积分货币获取途径以及用途的解读,想在本站混的好,请务必认真阅读!
3. 本站强烈打击盗版/破解等有损他人权益和违法作为,请各位会员支持正版!
4. 编程技术 > 如何使用killOp杀死Mongo中的长时间运行操作