Day896.MySql的kill命令 -MySQL实战

news2025/2/25 18:08:27

MySql的kill命令

Hi,我是阿昌,今天学习记录的是关于MySql的kill命令的内容。

在 MySQL 中有两个 kill 命令

  • 一个是 kill query + 线程 id,表示终止这个线程中正在执行的语句;
  • 一个是 kill connection + 线程 id,这里 connection 可缺省,表示断开这个线程的连接,当然如果这个线程有语句正在执行,也是要先停止正在执行的语句的。

不知道你在使用 MySQL 的时候,有没有遇到过这样的现象:使用了 kill 命令,却没能断开这个连接。再执行 show processlist 命令,看到这条语句的 Command 列显示的是 Killed。显示为 Killed 是什么意思,不是应该直接在 show processlist 的结果里看不到这个线程了吗?

大多数情况下,kill query/connection 命令是有效的。比如,执行一个查询的过程中,发现执行时间太久,要放弃继续查询,这时就可以用 kill query 命令,终止这条查询语句。还有一种情况是,语句处于锁等待的时候,直接使用 kill 命令也是有效的。

一起来看下这个例子:

图 1 kill query 成功的例子

可以看到,session C 执行 kill query 以后,session B 几乎同时就提示了语句被中断。这,就是预期的结果。


一、收到 kill 以后,线程做什么?

但是,停下来想一下:session B 是直接终止掉线程,什么都不管就直接退出吗?

显然,这是不行的。在全局锁和表锁中,当对一个表做增删改查操作时,会在表上加 MDL 读锁。所以,session B 虽然处于 blocked 状态,但还是拿着一个 MDL 读锁的。

如果线程被 kill 的时候,就直接终止,那之后这个 MDL 读锁就没机会被释放了。这样看来,kill 并不是马上停止的意思,而是告诉执行线程说,这条语句已经不需要继续执行了,可以开始“执行停止的逻辑了”

其实,这跟 Linux 的 kill 命令类似,kill -N pid 并不是让进程直接停止,而是给进程发一个信号,然后进程处理这个信号,进入终止逻辑。只是对于 MySQL 的 kill 命令来说,不需要传信号量参数,就只有“停止”这个命令。

实现上,当用户执行 kill query thread_id_B 时,MySQL 里处理 kill 命令的线程做了两件事:

  1. 把 session B 的运行状态改成 THD::KILL_QUERY(将变量 killed 赋值为 THD::KILL_QUERY);
  2. 给 session B 的执行线程发一个信号。

为什么要发信号呢?因为像图 1 的例子里面,session B 处于锁等待状态,如果只是把 session B 的线程状态设置 THD::KILL_QUERY,线程 B 并不知道这个状态变化,还是会继续等待。

发一个信号的目的,就是让 session B 退出等待,来处理这个 THD::KILL_QUERY 状态。

上面的分析中,隐含了这么三层意思:

  1. 一个语句执行过程中有多处“埋点”,在这些“埋点”的地方判断线程状态,如果发现线程状态是 THD::KILL_QUERY,才开始进入语句终止逻辑;
  2. 如果处于等待状态,必须是一个可以被唤醒的等待,否则根本不会执行到“埋点”处;
  3. 语句从开始进入终止逻辑,到终止逻辑完全完成,是有一个过程的。

到这里原来不是“说停就停的”。


看一个 kill 不掉的例子,也就是在MySQL 实例健康状态检测方法中提到的 innodb_thread_concurrency 不够用的例子。

首先,执行 set global innodb_thread_concurrency=2,将 InnoDB 的并发线程上限数设置为 2;

然后,执行下面的序列:

图 2 kill query 无效的例子

可以看到:

  1. sesssion C 执行的时候被堵住了;
  2. 但是 session D 执行的 kill query C 命令却没什么效果,
  3. 直到 session E 执行了 kill connection 命令,才断开了 session C 的连接,提示“Lost connection to MySQL server during query”,
  4. 但是这时候,如果在 session E 中执行 show processlist,你就能看到下面这个图。

图 3 kill connection 之后的效果

这时候,id=12 这个线程的 Commnad 列显示的是 Killed。也就是说,客户端虽然断开了连接,但实际上服务端上这条语句还在执行过程中。为什么在执行 kill query 命令时,这条语句不像第一个例子的 update 语句一样退出呢?

在实现上,等行锁时,使用的是 pthread_cond_timedwait 函数,这个等待状态可以被唤醒。

但是,在这个例子里,12 号线程的等待逻辑是这样的:每 10 毫秒判断一下是否可以进入 InnoDB 执行,如果不行,就调用 nanosleep 函数进入 sleep 状态。

也就是说,虽然 12 号线程的状态已经被设置成了 KILL_QUERY,但是在这个等待进入 InnoDB 的循环过程中,并没有去判断线程的状态,因此根本不会进入终止逻辑阶段。

而当 session E 执行 kill connection 命令时,是这么做的,

  1. 把 12 号线程状态设置为 KILL_CONNECTION;
  2. 关掉 12 号线程的网络连接。因为有这个操作,所以你会看到,这时候 session C 收到了断开连接的提示。

那为什么执行 show processlist 的时候,会看到 Command 列显示为 killed 呢?

其实,这就是因为在执行 show processlist 的时候,有一个特别的逻辑:

如果一个线程的状态是KILL_CONNECTION,就把Command列显示成Killed。

所以其实,即使是客户端退出了,这个线程的状态仍然是在等待中。那这个线程什么时候会退出呢?答案是,只有等到满足进入 InnoDB 的条件后,session C 的查询语句继续执行,然后才有可能判断到线程状态已经变成了 KILL_QUERY 或者 KILL_CONNECTION,再进入终止逻辑阶段。


小结一下。这个例子是 kill 无效的第一类情况,即:线程没有执行到判断线程状态的逻辑。跟这种情况相同的,还有由于 IO 压力过大,读写 IO 的函数一直无法返回,导致不能及时判断线程的状态。

另一类情况是,终止逻辑耗时较长。这时候,从 show processlist 结果上看也是 Command=Killed,需要等到终止逻辑完成,语句才算真正完成。这类情况,比较常见的场景有以下几种:

  1. 超大事务执行期间被 kill。这时候,回滚操作需要对事务执行期间生成的所有新数据版本做回收操作,耗时很长。大查询回滚。如果查询过程中生成了比较大的临时文件,加上此时文件系统压力大,删除临时文件可能需要等待 IO 资源,导致耗时较长。
  2. DDL 命令执行到最后阶段,如果被 kill,需要删除中间过程的临时文件,也可能受 IO 资源影响耗时较久。

如果直接在客户端通过 Ctrl+C 命令,是不是就可以直接终止线程呢?答案是,不可以。

这里有一个误解,其实在客户端的操作只能操作到客户端的线程,客户端和服务端只能通过网络交互,是不可能直接操作服务端线程的。而由于 MySQL 是停等协议,所以这个线程执行的语句还没有返回的时候,再往这个连接里面继续发命令也是没有用的。

实际上,执行 Ctrl+C 的时候,是 MySQL 客户端另外启动一个连接,然后发送一个 kill query 命令。所以,可别以为在客户端执行完 Ctrl+C 就万事大吉了。

因为,要 kill 掉一个线程,还涉及到后端的很多操作。


二、另外两个关于客户端的误解

1、如果库里面的表特别多,连接就会很慢。

有些线上的库,会包含很多表(我见过最多的一个库里有 6 万个表)。

每次用客户端连接都会卡在下面这个界面上。

图 4 连接等待

而如果 db1 这个库里表很少的话,连接起来就会很快,可以很快进入输入命令的状态。因此,有同学会认为是表的数目影响了连接性能。每个客户端在和服务端建立连接的时候,需要做的事情就是 TCP 握手、用户校验、获取权限。但这几个操作,显然跟库里面表的个数无关。

但实际上,正如图中的文字提示所说的,当使用默认参数连接的时候,MySQL 客户端会提供一个本地库名和表名补全的功能

为了实现这个功能,客户端在连接成功后,需要多做一些操作:

  1. 执行 show databases;
  2. 切到 db1 库,执行 show tables;
  3. 把这两个命令的结果用于构建一个本地的哈希表。

在这些操作中,最花时间的就是第三步在本地构建哈希表的操作。所以,当一个库中的表个数非常多的时候,这一步就会花比较长的时间。也就是说,感知到的连接过程慢,其实并不是连接慢,也不是服务端慢,而是客户端慢

图中的提示也说了,如果在连接命令中加上 -A,就可以关掉这个自动补全的功能,然后客户端就可以快速返回了。

这里自动补全的效果就是,你在输入库名或者表名的时候,输入前缀,可以使用 Tab 键自动补全表名或者显示提示。

实际使用中,如果你自动补全功能用得并不多,建议每次使用的时候都默认加 -A。

2、加–quick(或者简写为 -q) 参数,也可以跳过这个阶段

但是,这个–quick 是一个更容易引起误会的参数,也是关于客户端常见的一个误解。

设置了这个参数可能会降低服务端的性能。为什么这么说呢?MySQL 客户端发送请求后,接收服务端返回结果的方式有两种:

  1. 一种是本地缓存,也就是在本地开一片内存,先把结果存起来。如果你用 API 开发,对应的就是 mysql_store_result 方法。
  2. 另一种是不缓存,读一个处理一个。如果你用 API 开发,对应的就是 mysql_use_result 方法。

MySQL 客户端默认采用第一种方式,而如果加上–quick 参数,就会使用第二种不缓存的方式。

采用不缓存的方式时,如果本地处理得慢,就会导致服务端发送结果被阻塞,因此会让服务端变慢。

为什么要给这个参数取名叫作 quick 呢?

这是因为使用这个参数可以达到以下三点效果:

  • 第一点,跳过表名自动补全功能。
  • 第二点,mysql_store_result 需要申请本地内存来缓存查询结果,如果查询结果太大,会耗费较多的本地内存,可能会影响客户端本地机器的性能;
  • 第三点,是不会把执行命令记录到本地的命令历史文件。

–quick 参数的意思,是让客户端变得更快。


三、总结

这些“kill 不掉”的情况,其实是因为发送 kill 命令的客户端,并没有强行停止目标线程的执行,而只是设置了个状态,并唤醒对应的线程。而被 kill 的线程,需要执行到判断状态的“埋点”,才会开始进入终止逻辑阶段。

并且,终止逻辑本身也是需要耗费时间的。所以,如果发现一个线程处于 Killed 状态,可以做的事情就是,通过影响系统环境,让这个 Killed 状态尽快结束。比如,如果是第一个例子里 InnoDB 并发度的问题,就可以临时调大 innodb_thread_concurrency 的值,或者停掉别的线程,让出位子给这个线程执行。而如果是回滚逻辑由于受到 IO 资源限制执行得比较慢,就通过减少系统压力让它加速

做完这些操作后,其实已经没有办法再对它做什么了,只能等待流程自己完成


如果你碰到一个被 killed 的事务一直处于回滚状态,你认为是应该直接把 MySQL 进程强行重启,还是应该让它自己执行完成呢?为什么呢?

  1. 。死等。 重启依然需要回滚完之后,重启才能完成。
  2. 若影响了其他线程,可以进行主备切换。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/361758.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据宝应用场景】多场景,多接口,哪些数据可以用在文旅平台上?

随着云计算、物联网、互联网和移动智能终端等技术的飞速发展以及迎合游客不断升级的文旅消费需求,智慧旅游成为文旅行业信息建设的主要方向。 在信息化时代,游客对于文旅体验和文旅信息服务的要求在逐步提高。以现代科技为主要手段的智慧文旅&#xff0…

linux rsync服务端安装和windows客户端备份

安装:yum install -y rsync 密码内容:zhangsan:123456 配置文件:/etc/rsyncd.conf内容 # /etc/rsyncd: configuration file for rsync daemon mode # See rsyncd.conf man page for more options. # configuration example: uid root gi…

从0开始的ios自动化测试

最近由于工作内容调整,需要开始弄ios自动化了。网上信息有点杂乱,这边我就按我的实际情况,顺便记录下来,看是否能帮到有需要的人。 环境准备 安装tidevice pip3 install -U “tidevice[openssl]” 它的作用是,帮你绕…

JavaScript从零开始 学习记录(一)

前言 选择视频课程之前,不仅查阅了资料,还询问了网友,最终敲定了学习黑马前端的视频教程,学了5小节,发现挺对自己口味的且从反响来看,还是相当不错的,便打算利用这个寒假学完 笔记范围 从这节…

领航智能汽车信息安全新征程 | 云驰未来乔迁新址

2月20日,在北京朝阳百子湾东朝时代创意园,云驰未来迎来乔迁之喜,智能汽车和自动驾驶领域的行业领导、合作伙伴与客户、投资人及媒体嘉宾齐聚现场,共同见证云驰未来迈上新的发展征程。 作为中国智能网联汽车和自动驾驶信息安全行业…

图床(Typora + uPic/PicGo +七牛云)

图床(Typora uPic/PicGo 七牛云) 笔者平时使用 Typora 编写 markdown 文档,文档中常常会放置图片,如果文档不需要分享的话,其实讲图片存放在本地就可以了。由于我有在多台机器编写 markdown 笔记,还有将…

维度建模基本流程总结

一、维度建模基本流程图数据RD进行业务调研和数据现状调研,产出符合相关模版规范的业务知识文档和数据现状文档。数据PM也会调研相关业务产出需求设计文档,三方参与需求评审,评审通过后基建数据RD进行需求拆解,产出技术方案&#…

redhawk:GSC file与STA file

1.GSC file redhawk做lowpower分析时需要GSC&#xff08;Global Switching Configuration&#xff09;file指导block/instance/power domain的开关状态。 Syntax&#xff08;in GSR file&#xff09;: GSC_FILES <gsc_FilePathName> Syntax&#xff08;in GSC file&a…

django项目实战八(django+bootstrap实现增删改查)进阶验证码

目录 一、安装第三方 1、pillow 2、第三方字体文件 二、实现生成验证码 1、创建code.py 2、url 3、修改auth.py 4、修改account.py 5、修改login.html 三、验证码校验 1、验证码写入到session 2、修改form下的LoginForm类新增code字段 3、修改login.html 4、修改acco…

Jasperreort使用

准备工作 下载Jaspersoft Studio 下载地址 下载后一直下一步安装 Studio基本使用 新建项目 新建模板 具体制作教程可前往B站搜索视频教程 添加中文字体 如果不添加&#xff0c;后面打印出PDF的时候中文显示不出来 电脑自带的字体一般在C:\Windows\Fonts 但该目…

6——JVM调优工具详解及调优实战

Jmap、Jstack、Jinfo命令详解 Jmap 此命令可以用来查看内存信息&#xff0c;实例个数&#xff0c;以及占用内存大小 生成dump文件 把dump文件装入Jvisvalvm进行分析 Jstack Jstack加进程id查找死锁 Jstack找出占CPU最高的线程堆栈信息 top -p 进程号&#xff1a;显示进程…

文件系统概念

1.文件逻辑结构 (1)有结构文件和无结构文件 ①定长记录 ②可变长记录 (2)顺序文件 (3)索引文件 (4)索引顺序文件 (5)多级索引顺序文件 2.文件目录 (1)文件控制块 (2)目录结构 (3)索引节点 3.文件的物理结构 (1)文件块&#xff0c;磁盘块 (2)文件分配方式 ①连续分配 ②链接…

跑步戴哪种耳机好,最适合运动跑步的蓝牙耳机

经常跑步使用的耳机&#xff0c;还是要选择佩戴着舒适以及牢固的运动耳机最为合适&#xff0c;在运动当中会遇到耳机掉落或者长时间佩戴耳道感到难受的现象发生&#xff0c;那么什么蓝牙耳机是最适合运动当中佩戴呢&#xff1f;下面这些耳机分享希望能够帮助大家。 1、南卡Run…

人工智能基础部分13-LSTM网络:预测上证指数走势

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下LSTM网络&#xff0c;主要运用于解决序列问题。 一、LSTM网络简单介绍 LSTM又称为&#xff1a;长短期记忆网络&#xff0c;它是一种特殊的 RNN。LSTM网络主要是为了解决长序列训练过程中的梯度消失和梯度爆炸问题…

CATCTF wife原型链污染

CATCTF wife原型链污染 原型链污染原理&#xff1a;https://drun1baby.github.io/2022/12/29/JavaScript-%E5%8E%9F%E5%9E%8B%E9%93%BE%E6%B1%A1%E6%9F%93/ 如下代码&#xff0c;prototype是newClass类的一个属性。newClass 实例化的对象 newObj 的 .__proto__ 指向 newClass…

数字证书不仅有SSL证书,数字证书类型科普大全

数字证书不仅有SSL证书&#xff0c;数字证书类型科普大全证书不单单有SSL证书&#xff0c;还有SSL证书、代码签名证书以及客户端证书等。具体分类跟着陕西CA一起来看看吧。SSL证书&#xff1a;单域名SSL证书、多域名SSL证书、通配符SSL证书代码签名证书&#xff1a;单位代码签名…

管理系统权限分析以及白屏处理

菜单权限的业务分析 超级管理员&#xff1a;首页、权限模块、商品模块 不同角色能看到的菜单是不一样的。 如何实现菜单的权限 登录时向服务器发请求&#xff0c;服务器会把用户相应的菜单的权限信息&#xff0c;返回给前端&#xff0c;可以根据服务器返回的数据&#xff0…

sql复习(set运算符、高级子查询)

一、set运算符 union&#xff1a;得到两个查询结果的并集&#xff0c;并且⾃动去掉重复⾏。不会排序 union all&#xff1a;得到两个查询结果的并集&#xff0c;不会去掉重复⾏。也不会排序 intersect&#xff1a;得到两个查询结果的交集&#xff0c;并且按照结果集的第⼀个列进…

JavaSEI学习day10 基础班知识点回顾

一. 注释 注释是对代码的一种解释,在程序 的指定位置, 添加的一些说明性信息被注释掉的内容, 不会参与程序的编译和运行. 分类:单行: // 注释信息多行: /* 注释信息 */文档: /** 注释信息 */ 二. 关键字 Java语言中有特殊含义的单词&#xff0c;就是关键字。在后面的课程中…

基于Django的员工管理系统

目录 一、新建项目 二、创建app 三、设计表结构 四、在MySQL中生成表 五、静态文件管理 六、添加页面 七、模板的继承 一、新建项目 django-admin startproject 员工管理系统 二、创建app startapp app01 三、设计表结构 app01/migrations/models.py from django.db impo…