MySQL 实战 45 讲
林晓斌
网名丁奇,前腾讯云数据库负责人
224874 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 49 讲
实践篇 (37讲)
特别放送 (1讲)
结课测试 (1讲)
MySQL 实战 45 讲
15
15
1.0x
00:00/00:00
登录|注册

32 | 为什么还有kill不掉的语句?

Ctrl+C命令的限制
无法直接操作服务端线程
--quick参数的误解
自动补全功能导致的连接慢
Command列显示为Killed
kill connection有效
kill query无效
客户端操作的限制
客户端连接慢的误解
终止逻辑耗时较长
线程没有执行到判断线程状态的逻辑
发送信号给执行线程
改变线程状态
终止处于锁等待的语句
终止正在执行的语句
kill connection +线程id
kill query +线程id
解决kill不掉的问题的方法
kill不掉的情况和客户端误解
kill命令的作用和实现
--quick参数的误解
表数目影响连接性能的误解
DDL命令执行到最后阶段被kill
大查询回滚
超大事务执行期间被kill
innodb_thread_concurrency不够用的例子
客户端误解
kill不掉的情况
kill命令的实现
kill命令的有效性
MySQL中的kill命令
总结
客户端误解
终止逻辑耗时较长的情况
kill不掉的例子
为什么还有kill不掉的语句?

该思维导图由 AI 生成,仅供参考

在 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 几乎同时就提示了语句被中断。这,就是我们预期的结果。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

MySQL中的kill命令有两种形式:kill query和kill connection,分别用于终止正在执行的语句和断开连接。然而,有时候执行kill命令却无法生效,导致语句仍在执行。这种情况可能是因为线程没有执行到判断线程状态的逻辑,或者是由于终止逻辑耗时较长。例如,在超大事务执行期间被kill时,回滚操作需要对事务执行期间生成的所有新数据版本做回收操作,耗时很长。另外,文章还提到了客户端通过Ctrl+C命令无法直接终止线程,因为客户端和服务端只能通过网络交互,无法直接操作服务端线程。因此,要kill掉一个线程,还涉及到后端的很多操作。这些情况都说明了kill命令在MySQL中的一些特殊情况和限制。 另外,文章还介绍了MySQL客户端的一些误解,如表的数量影响连接性能的误解以及关于客户端参数--quick的误解。通过具体的例子和技术细节,深入浅出地解释了这些误解的原因和解决方法。 总的来说,本文通过具体的例子和技术细节,深入浅出地解释了kill命令的工作原理和可能遇到的问题,以及MySQL客户端的一些误解。这些内容对读者快速了解MySQL中kill命令的使用和限制具有一定的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《MySQL 实战 45 讲》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(51)

  • 最新
  • 精选
  • geraltlaush
    置顶
    kill connection本质上只是把客户端的sql连接断开,后面的执行流程还是要走kill query的,是这样理解吧

    作者回复: 这个理解非常到位👍 额外的一个不同就是show processlist的时候,kill connection会显示“killed” 这两句加起来可以用来替换我们文中的描述👍

    2019-01-30
    124
  • learn more
    老师好,文中 set global innodb_thread_concurrency=2的那个例子,前面 Session A 和 Session B 已经占用了两个线程了,那为什么我们还可以在一个新的Session中执行 Kill 或 show full processlist 命令呢?

    作者回复: 执行kill的时候没进InnoDB,不受这个参数限制的

    2019-12-26
    97
  • Mr.sylar
    老师,我想问下这些原理的"渔"的方法除了看源码,还有别的建议吗

    作者回复: 不同的知识点不太一样哈, 有些可以看文档; 有些可以自己验证; 还有就是看其他人文章,加验证;(就是我们这个专栏的方法^_^)

    2019-01-25
    2
    22
  • wjz1991
    老师,之前也是有遇到程序问题导致cpu爆满,临时先把innodb_thread_concurrency设置为16(降低cpu避免影响同机器实例),然后不断去kill,后面程序人员修复了这个问题后,一堆的killed的语句不释放,设置innodb_thread_concurrency=0,等了半个月都没释放,后面还是安排主从切换,强制重启解决,请问老师,这是为什么?

    作者回复: 如果是因为这个原因的,应该是设置innodb_thread_concurrency=0就会退出的。。 你这个情况可能卡在别的地方了,下次如果再出现,要重启之前,用pstack保留个现场哦

    2019-02-13
    3
    19
  • Lukia
    请教老师,删除中间列和修改末尾列这两种DDL的差别在什么地方呢? 作者回复: 对,其实只有 改索引、 加最后一列、删最后一列 其他的大多数不行,比如删除中间一列这种

    作者回复: 删除中间列,就没办法用切换的那个方案。 MySQL的备库比主库多一个字段或少一个字段,这时候日志还是可以应用成功的(但如果少的是中间一个字段,字段就会对应错了)

    2019-02-19
    4
    16
  • HuaMax
    课后题。我认为需要看当时的业务场景。重启会导致其他的连接也断开,返回给其他业务连接丢失的错误。如果有很多事务在等待该事务的锁,则应该重启,让其他事务快速重试获取锁。另外如果是RR的事务隔离级别,长事务会因为数据可见性的问题,对于多版本的数据需要找到正确的版本,对读性能是不是也会有影响,这时候重启也更好。个人理解,请老师指正。

    作者回复: 有考虑到对其他线程的影响,这个👍 其实这种时候往往是要先考虑切换(当然重启也是切换的) 如果只看恢复时间的话,等待会更快

    2019-01-26
    13
  • 700
    老师,请教。 1)文中开头说“当然如果这个线程有语句正在执行,也是要先停止正在执行的语句的”。我个人在平时使用中就是按默认的执行,不管这个线程有无正在执行语句。不知这样会有什么潜在问题? 2)文中说“实际上,执行 Ctrl+C 的时候,是 MySQL 客户端另外启动一个连接,然后发送一个 kill query 命令“。这个怎么解释呢? 我开启 general log 的时候执行 Ctrl+C 或 Ctrl+D 并没有看到有另外启动一个连接,也没有看到 kill query 命令。general log 中仅看到对应线程 id 和 Quit。 3)MySQL 为什么要同时存在 kill query 和 kill connection,既然 kill query 有无效的场景,干嘛不直接存在一个 kill connection 命令就好了?那它俩分别对应的适用场景是什么,什么时候考虑 kill query,什么时候考虑 kill connection?我个人觉得连接如果直接被 kill 掉大不了再重连一次好了。也没啥损失。 4)小小一个总结,不知对否? kill query - 会出现无法 kill 掉的情况,只能再次执行 kill connection。 kill connection - 会出现 Command 列显示成 Killed 的情况。

    作者回复: 1. 一般你执行kill就是要停止正在执行的语句,所以问题不大😋 2. 不应该呀, KILL QUERY 是大写哦,你再grep一下日志; 3. 多提供一种方法嘛。kill query是指你只是想停止这个语句,但是事务不会回滚。一般kill query是发生在客户端执行ctrl+c的时候啦。平时紧急处理确实直接用kill + thread_id。 好问题 4. 对,另外,在kill query无效的时候,其实kill connection也是无效的

    2019-01-25
    6
    13
  • gaohueric
    老师您好,一个表中 1个主键,2个唯一索引,1个普通索引 4个普通字段,当插入一条全部字段不为空的数据时,此时假设有4个索引文件,分别对应 主键 唯一性索引,普通索引,假设内存中没有这个数据页,那么server是直接调用innodb的接口,然后依次校验 (读取磁盘数据,验证唯一性)主键,唯一性索引,然后确认无误A时刻之后,吧主键和唯一性索引的写入内存,再把普通索引写入change buffer?那普通数据呢,是不是跟着主键一块写入内存了?

    作者回复: 1. 是的,如果普通索引上的数据页这时候没有在内存中,就会使用change buffer 2. “那普通数据呢,是不是跟着主键一块写入内存了?” 你说的是无索引的字段是吧,这些数据就在主键索引上,其实改的就是主键索引。

    2019-01-26
    11
  • 700
    老师,您好。客户端版本如下: mysql Ver 14.14 Distrib 5.7.24, for linux-glibc2.12 (x86_64) using EditLine wrapper 老师,再请教另一个问题。并非所有的 DDL 操作都可以通过主从切换来实现吧?不适用的场景有哪些呢?

    作者回复: 对,其实只有 改索引、 加最后一列、删最后一列 其他的大多数不行,比如删除中间一列这种

    2019-01-27
    9
  • 千年孤独
    可能不是本章讨论的问题,我想请问老师“MySQL使用自增ID和UUID作为主键的优劣”,基于什么样的业务场景用哪种好?

    作者回复: 后面会有文章会提到这个问题哈:)

    2019-01-27
    4
收起评论
显示
设置
留言
51
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部