mongo 连接二三事
如果你也被慢查询、CPU 打满、雪崩等问题困扰,盘它!
查看实例上的慢查询
查询语句说明
假设我们想查询实例上所有执行时间超过 1s
的慢语句。
如果想要查看指定 db 上的慢查询:
查询结果分析
截取其中一条语句进行分析:
所有输出的这些字段,都可以用于查询条件,常用的有:
字段名
说明
client
该语句来自于哪个客户端
可用于查询指定客户端的请求
opid
该操作的唯一标识
db.killOp()时使用此字段的值
active
操作是否已启动
空闲连接或者内部线程该字段为false
某些已经让步的操作,状态仍可能为 true
secs_running
操作已开始多长时间(秒)
当 active 为 true 时,该字段有值
microsecs_running
操作已开始多长时间(微秒)
当 active 为 true 时,该字段有值
op
操作类型,query、insert、command……
ns
namespace, db.collection 的形式
command
语句具体的执行信息
planSummary
执行计划,可用于慢语句分析
locks
操作对哪些模块加什么类型的锁
模块:
Global
MMAPV1Journal
Database
Collection
Metadata
oplog
锁类型:
R-读锁 W-写锁
r-读意向锁 w-写意向锁
waitingForLock
true:正在等锁
false:已经获得锁
连接处理
kill 指定操作
当慢查询严重,异常连接数过多(或者正常连接数过多),为了保证大局稳定,我们需要“牺牲”部分连接。
MongoDB 提供如下方法,可以杀掉任意执行中的操作:
其中 opid
为上文所述 db.currentOp()
中展示的 opid
。
killOp 原理
每个连接对应的服务线程存储了一个killPending的字段,当发送killOp时,会将该字段置1;请求在执行过程中,可以通过不断的调用OperationContext::checkForInterrupt()来检查killPending是否被设置,如果被设置,则线程退出。
一个请求要支持 killOp,必须在请求的处理逻辑里加上 checkForInterrupt() 检查点才行,否则即使发送了 killOp,也只能等待请求完全处理完毕线程才会退出。
比如 createIndex 的处理逻辑里包含了类似如下的代码,在 createIndex 的循环过程中,一旦 killPending 被置1了,createIndex 的执行可以在当前循环结束时退出。
所以发送 killOp 后,请求要执行到下一个『检查点』线程才会退出,MongoDB 在很多可能耗时长的请求中,都加入了checkForInterrupt()检查点,如创建索引,repair database,mapreduce、aggregation等。
ctrl + c 是否可立即终止操作?
Ctrl + C
会关闭 client
到 server
的连接,但后端的线程不会立即结束(MongoDB每个连接的请求由一个对应的线程来处理),而是会一直执行下去。
直到执行结束后,给 client
端发送通知,会发现连接已经断开,这时线程才会退出。
这个时候就需要使用 killOp
去实现真正的“终止”,操作点会在下个检查点
结束执行,整个线程退出。
最后更新于
这有帮助吗?