MongoDB 4.4 db.currentOp() 和 db.killOp() 方法说明

1 db.currentOp() 方法


1.1 db.currentOp() 概述

官网说明如下:

https://www.mongodb.com/docs/manual/reference/method/db.currentOp/

db.currentOp()方法会返回数据库实例当前操作的信息,是数据库命令currentOp的封装。

语法:

db.currentOp( )

operations 是可选项。 可以是boolean 或者 document 类型。 当指定true时,会包含空闲连接和系统操作。当指定查询条件的filter文档时,则只返回匹配条件的操作。

db.currentOp()支持的filter文档有如下3种类型:

 

  1. “$ownOps”: 布尔型,当设置为true时,只返回当前用户的操作信息。
  2. “$all”:布尔型,当设置为true时,返回所有操作的信息,包括空闲连接和系统操作。
  3. :根据output fields指定过滤条件。 当”$all”: true 和 output fields 同时存在时,只有”$all”: true生效。

完整的output fields 参考官网链接:

https://www.mongodb.com/docs/manual/reference/command/currentOp/#std-label-currentOp-output-fields

db.currentOp(true) 和 db.currentOp( { “$all”: true } ) 是等效的,查询结果相同。

Db.currentOp() 和 database profiler 一样对所有的CRUD操作输出相同的基本诊断信息,具体如下:

  1. aggregate
  2. count
  3. delete
  4. distinct
  5. find (OP_QUERY and command)
  6. findAndModify
  7. getMore (OP_GET_MORE and command)
  8. insert
  9. mapReduce
  10. update

这些操作也同样会记录在慢查询日志中(slowOpThresholdMs )。

MongoDB 4.4 数据库分析器(Database Profiler)
https://www.cndba.cn/dave/article/107982

1.2 db.currentOp() 示例

以下代码查询正在等待lock的所有写操作信息:

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

以下代码查询所有活动但没有工作(active but no yield)的操作:

db.currentOp(
{
"active" : true,
"numYields" : 0,
"waitingForLock" : false
}
)

以下代码查询db1 数据库上所有执行超过3秒的活动会话:

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

以下代码查询正在创建索引的操作:

db.adminCommand(
{
currentOp: true,
$or: [
{ op: "command", "command.createIndexes": { $exists: true } },
{ op: "none", "msg" : /^Index Build/ }
]
}
)

输出结果列的描述参考官网链接:

https://www.mongodb.com/docs/manual/reference/command/currentOp/#std-label-currentOp-output-fields

2 db.killOp()方法


2.1 db.killOp() 概述

官网说明如下:

 

https://www.mongodb.com/docs/manual/reference/method/db.killOp/

db.killOp(opid) 方法根据指定的操作ID 来中断操作。 可以使用db.currentOp()来查看opid。

中断正在运行的操作是一项非常危险的操作,只能用db.killOp() 方法来中断客户端的操作,不能用来中断数据库内部的操作。

2.2 Sharded Cluster 中的db.killOp() 操作

Shard cluster 环境下,读写操作可能会在多个shard 上有会话信息,所以killOp()需要同时kill 掉这些会话。 MongoDB 4.0 后在一个shard节点上执行时,会同步kill 掉其他节点上的操作,之前的版则需要手工分别kill 这些操作。

2.2.1 Kill Read Operations

2.2.1.1 MongoDB 4.0+

从MongoDB 4.0 开始,db.killOp() 可以在mongos上运行,并且可以kill在所有shard上运行的 read 操作。

2.2.1.1.1 在mongos 实例上执行

在客户端连接的mongos 上(必须在这个节点)执行聚合查询获取opid:

 

use admin
db.aggregate( [
{ $currentOp : { allUsers: true, localOps: true } },
{ $match : <filter condition> } // Optional. Specify the condition to find the op.
// e.g. { op: "getmore", "command.collection": "someCollection" }
] )

然后根据查询到的opid ,在对应的mongos上进行kill:

 

db.killOp( )

2.2.1.1.2 在shard 实例上执行

也可以在操作运行的shard 实例上查找并kill read 操作。 MongoDB 4.0+ 会自动将kill 操作发送到其他shard 节点和mongos 实例。

在执行操作的shard 节点上查找opid:

use admin
db.aggregate( [
{ $currentOp : { allUsers: true } },
{ $match : <filter condition> } // Optional. Specify the condition to find the op.
// e.g. { op: "getmore", "command.collection": "someCollection" }
] )

在shard 实例上执行db.killOp()命令:

db.killOp( )

MongoDB 4.0+ 会将kill 操作发送到其他shard 节点和mongos 节点。

2.2.1.2 MongoDB 3.6 之前的版本

在MongoDB 3.6 之前的sharded cluster中,如果要kill 一个查询操作,还必须kill掉关联的shard节点上的查询操作。

在mongos 实例上执行聚合管道命令:$currentOp 来查找查询操作的shard 节点。

use admin
db.aggregate( [
{ $currentOp : { allUsers: true } },
{ $match : <filter condition> } // Optional. Specify the condition to find the op.
// e.g. { op: "getmore", "command.collection": "someCollection" }
] )

$currentOp 命令会以/”shardName : opid on that shard”的格式返回opids信息:

{
"shard" : "shardB",
..
"opid" : "shardB:79014",
...
},
{
"shard" : "shardA",
..
"opid" : "shardA:100813",
...
},

在mongos 节点执行db.killOp()来kill 所有shard的操作。

db.killOp(“shardB:79014”);
db.killOp(“shardA:100813”);

2.2.2 Kill Write Operations

2.2.2.1 Within a Session

从MongoDB 3.6 开始,MongoDB驱动程序将除未确认的写操作外的所有操作与server session关联。

Server Sessions
https://www.mongodb.com/docs/manual/reference/server-sessions/

如果写操作已经关联到了server session,那么可以在mongos 节点执行killSessions 命令来kill 跨shard的写操作。

2.2.2.1.1 MongoDB 4.0+

在mongos 节点执行聚合管道命令$currentOp来查找lsid (logical session id).

 

use admin
db.aggregate( [
{ $currentOp : { allUsers: true, localOps: true } },
{ $match : <filter condition> } // Optional. Specify the condition to find the op.
// e.g. { "op" : "update", "ns": "mydb.someCollection" }
] )

根据lsid,在mongos 节点,执行killSessions 命令来kill 所有分片上的操作:

db.adminCommand( { killSessions: [
{ "id" : UUID("80e48c5a-f7fb-4541-8ac0-9e3a1ed224a4"), "uid" : BinData(0,"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=") }
] } )

2.2.2.1.2 MongoDB 3.6

在mongos 节点或者分别在每个shard上执行$currentOp 命令来查找lsid (logical session id):

use admin
db.aggregate( [
{ $currentOp : { allUsers: true } },
{ $match : <filter condition> } // Optional. Specify the condition to find the op.
// e.g. { "op" : "update", "ns": "mydb.someCollection" }
] )

根据lsid,在mongos 节点,执行killSessions 命令来kill 所有分片上的操作:

db.adminCommand( { killSessions: [
{ "id" : UUID("80e48c5a-f7fb-4541-8ac0-9e3a1ed224a4"), "uid" : BinData(0,"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=") }
] } )

2.2.2.2 Without a Session

如果写操作没有关联到server session,那么必须kill 所有shards上的写操作。

在mongos 节点执行$currentOp命令查找所有shard上运行的查询操作:

use admin
db.aggregate( [
{ $currentOp : { allUsers: true } },
{ $match : <filter condition> } // Optional. Specify the condition to find the op.
] )

$currentOp命令会以”shardName : opid on that shard “的格式返回opids的信息:

{
"shard" : "shardB",
..
"opid" : "shardB:79214",
...
},
{
"shard" : "shardA",
..
"opid" : "shardA:100913",
...
},

然后在mongos 节点执行killOp()命令来kill 所有分片上的操作:

db.killOp(“shardB:79014”);
db.killOp(“shardA:100813”);

版权声明:本文为博主原创文章,未经博主允许不得转载。

 
 
posted @ 2022-06-24 17:29  seasonzone  阅读(1183)  评论(0编辑  收藏  举报