MongoDB killOp 案例详解

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 Tair(兼容Redis),内存型 2GB
简介: MongoDB 提供 currentOp 命令,列出当前正在执行的查询操作,并提供 killOp 命令,用于中止一些耗时比较长,影响线上业务的操作,作为一种应急手段。 下图是一个 currentOp 命令的输出项之一,用户在获取到 opid 后,调用 killOp() 并没有把这个请求干掉。

MongoDB 提供 currentOp 命令,列出当前正在执行的查询操作,并提供 killOp 命令,用于中止一些耗时比较长,影响线上业务的操作,作为一种应急手段。

下图是一个 currentOp 命令的输出项之一,用户在获取到 opid 后,调用 killOp() 并没有把这个请求干掉。

_2019_05_23_12_25_34

为什么 opid 是负数?

opid 在 mongod 里是一个 uint32 类型的整数,当你从 mongo shell 里看到 opid 为负数时,说明你的 mongod 已经成功执行超过21(INT32_MAX)次请求了,相当牛逼。

MongoDB 客户端与server是通过 BSON 来交换数据的,而在 bson 标准里,是没有 uint32 类型的,所以 opid 最终是以 int32 传递给客户端的,shell 拿到这个opid,当这个值超过 INT32_MAX 时,打印出来就是负数了。

负数的 opid 会 kill 会不掉么?

MongoDB 3.2.5 之前的确是有这个 bug,没有考虑到负数的情况,在 SERVER-23066 里已经修复了,阿里云上3.2、3.4、4.0 的最新版本均已修复这个问题。

修复的代码也很简单,就是接收到负数opid时,将其转换为 uint32 类型,详见 SERVER-23066 Make killOp accept negative opid

mongod 既然已经修复了,负数 opid 还是 kill 不掉?

此时 killOp 不成功,已经跟 opid 是否是负数没有关系了,本来在 MongoDB 的设计里,也不是所有操作都能被 kill 的。

killOp 的原理,为什么 killOp 能干掉请求?

MongoDB 一个用户连接,后端对应一个线程,本身一个请求开始后,会有一个线程一直执行,直到结束。能被 killOp 杀掉的请求,是因为请求在执行过程中会检测,是否收到了 kill 信号,如果收到了,就走结束请求的逻辑。所以 killOp 的作用也只是给对应的操作一个 kill 信号标志而已。

SomeCommand::Run() 
{
   for (someCondition) {
       doSomeThing();
       if (killOpReceived) { // SomeCommand 主动检测了 killOp 的信号,才能被 kill 掉
         break;
       }
   }
}

什么样的操作需要被 kill 掉?

运行逻辑很简单、开销很低的命令无需捕获 killOp 信号,这种操作 kill 掉也没什么意义,解决不了根本问题。而复杂命令,比如 find、update、createIndex、aggregation 等操作,可能持续遍历很多条记录,才一定需要具备被 kill 的能力。MongoDB 会在执行这些命令的执行逻辑里加入检查是否收到 kill 命令的逻辑。

加了 killOp 检测逻辑的命令,就一定能立马被 kill?

不一定,一个操作比如 createIndex,会分为很多步骤,命令解析、加锁、执行具体命令逻辑、释放锁、回包等,只有命令执行到具体执行逻辑里时,killOp 才会生效,如果一个操作还没有成功加上锁,本身每占用什么资源,而且对应的线程也没有执行,killOp 是不会生效的。

query 操作为什么会加写锁?

正常只读的请求、如 find、listIndexes 都是不会加写锁,但当 MongoDB 开启 profiling 的时候,请求执行超过一定阈值(默认100ms)的请求,会记录到 db.system.profile capped colleciton 里,写这个集合就需要加意向写锁(w),同时对于 capped collection 的写入,会有一个特殊的 METADATA 互斥写锁(W),有兴趣的研究代码,关键字列在下面.

const ResourceId resourceCappedInFlightForOtherDb =
    ResourceId(RESOURCE_METADATA, ResourceId::SINGLETON_CAPPED_IN_FLIGHT_OTHER_DB);
    
Lock::ResourceLock cappedInsertLockForLocalDb(
    txn->lockState(), resourceCappedInFlightForLocalDb, MODE_X);
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
NoSQL 安全 Java
SpringBoot系列(2)整合MongoDB实现增删改查(完整案例)
自己本科时候一直使用的是Mysql,目前的课题组使用的是MongoDB,因此就花了一部分时间整理了一下,实现springboot与MongoDB的整合,并且实现基本的增删改查操作,从头到尾给出一个完整的案例。
1052 0
SpringBoot系列(2)整合MongoDB实现增删改查(完整案例)
|
SQL NoSQL MongoDB
『MongoDB』MongoDB聚合框架深度解析及丰富的聚合查询案例
📣读完这篇文章里你能收获到 - MongoDB聚合框架的概念知识 - MongoDB的复杂聚合查询 - MQL与SQL的对比 - MQL聚合查询转换成相应语言的代码
686 1
『MongoDB』MongoDB聚合框架深度解析及丰富的聚合查询案例
|
存储 缓存 NoSQL
BigData之MongoDB:MongoDB基于分布式文件存储数据库的简介、下载、案例应用之详细攻略
BigData之MongoDB:MongoDB基于分布式文件存储数据库的简介、下载、案例应用之详细攻略
|
2月前
|
NoSQL MongoDB 数据库
python3操作MongoDB的crud以及聚合案例,代码可直接运行(python经典编程案例)
这篇文章提供了使用Python操作MongoDB数据库进行CRUD(创建、读取、更新、删除)操作的详细代码示例,以及如何执行聚合查询的案例。
33 6
|
5月前
|
NoSQL 物联网 atlas
智能制造案例专题|与MongoDB一起解锁工业4.0转型与增长的无限潜力!
欢迎访问MongoDB中文官网 https://www.mongodb.com/zh-cn 了解更多智能制造业的MongoDB解决方案
5410 2
|
5月前
|
NoSQL 物联网 atlas
|
6月前
|
NoSQL MongoDB 数据库
MongoDB数据恢复—MongoDB数据库文件被破坏的数据恢复案例
服务器数据恢复环境: 一台Windows Server操作系统服务器,服务器上部署MongoDB数据库。 MongoDB数据库故障&检测: 工作人员在未关闭MongoDB数据库服务的情况下,将数据库文件拷贝到其他分区。拷贝完成后将原MongoDB数据库所在分区进行了格式化操作,然后将数据库文件拷回原分区,重新启动MongoDB服务,服务无法启动。
|
6月前
|
存储 NoSQL 数据挖掘
MongoDB 实时分析案例
【5月更文挑战第7天】
201 0
|
存储 NoSQL 关系型数据库
数据库数据恢复——MongoDB数据库数据恢复案例
MongoDB数据库是文档数据存储库,将文档存储在集合之中,不是像MySQL一样的关系型数据库。 MongoDB数据库是开源数据库,同时提供具有附加功能的商业版本。 MongoDB数据库中的数据是以键值对(key-value pairs)的形式显示的,因此在模式设计上数据库受到的约束少,非常适合具有快速增长或其他变化需求的数据。
数据库数据恢复——MongoDB数据库数据恢复案例
|
11月前
|
NoSQL MongoDB 数据库
数据库数据恢复—Windows server环境下MongoDB数据库数据恢复案例
MongoDB数据库数据恢复环境: 一台Windows Server操作系统的虚拟机,虚拟机上部署有MongoDB数据库。 MongoDB数据库故障&检测: 在未关闭MongoDB服务的情况下,工作人员将MongoDB数据库文件拷贝到其他分区,然后将原数据库文件所在分区进行了格式化的操作,格式化完成后将数据库文件拷回原分区,重新启动MongoDB服务,发现MongoDB服务无法启动并报错。
数据库数据恢复—Windows server环境下MongoDB数据库数据恢复案例