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

news/2025/9/20 18:40:12/文章来源:https://www.cnblogs.com/san-mu/p/19102719

MySQL有两个kill命令:

  • kill query+线程id,表示终止该线程正在执行的语句;

  • kill (connection)+线程id,表示断开这个线程的连接,如果线程有语句正在执行,会先停止正在执行的语句。

有时候可能会遇到:使用了kill,却没能断开该连接,再执行show processlist时,看到这条语句的command列显示的是killed。

那这是什么意思呢?不是应该直接在show processlist结果里看不到这个线程了吗?本文就来讨论该问题。

收到kill后,线程做什么?

比如有一个场景:

session C执行kill query后,session B几乎同时提示了语句被中断,这是预期结果。那么session B是直接终止掉线程,什么都不管直接退出吗?

不是的,session在处于blocked状态时,还是拿着一个MDL读锁的,如果kill时直接终止,该读锁就没机会释放。这样看的话,kill并不是马上停止的意思,而是告诉执行线程该语句已经不需要继续执行,可以开始“执行停止逻辑”了。

当session C执行kill语句,MySQL里处理kill命令的线程会做两件事:

  • 将session B的运行状态改成THD::KILL_QUERY(将变量killed赋值为THD::KILL_QUERY);

  • 给session B的执行线程发一个信号,目的是让session B退出锁等待,来处理THD::KILL_QUERY状态。

上面的分析隐含了一些意思:

  • 一个语句执行过程中有多处埋点,在这些埋点地方判断线程状态,如果发现状态时THD::KILL_QUERY,才开始进入语句终止逻辑;

  • 如果处于等待状态,必须是一个可以被唤醒的等待,否则不会执行到埋点处;

  • 语句从开始进入终止逻辑,到终止逻辑完全完成,是有一个过程的。

接下来看一个kill不掉的例子。首先执行set global innodb_thread_concurrency=2,将InnoDB并发线程上限数设置为2,然后执行下面的序列:

  • session C执行时blocked;

  • session D的kill query C没产生效果;

  • session E执行kill connection,才断开session C的连接;

  • 但若此时在session E执行show processlist,结果如下:

此时id=12的command列显示killed,说明客户端虽然断开了连接,但实际服务端上这条语句还在执行过程中。

这里为什么和第一个例子不同呢?

在实现上,等待行锁使用的是pthread_cond_timedwait函数,该等待状态可以被唤醒。但这里12号线程的等待逻辑是每10毫秒判断是否可以进入InnoDB执行,如果不行就调用nanosleep函数进入sleep状态。也就是说,虽然12号线程状态已被设置为KILL_QUERY,但在等待进入InnoDB循环的过程中,并未判断线程的状态,因此不会进入终止逻辑阶段。

当session E执行kill connection时:

  • 将12号线程状态设置为KILL_CONNECTION;

  • 关掉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,需要等到终止逻辑完成,语句才算真正完成,这类情况常见场景有以下几种:

  • 超大事务执行期间被kill,此时回滚需要对事务执行期间所有新数据版本做回收,耗时很长;

  • 大查询回滚,删除查询过程生成的大临时文件,加上此时文件系统压力大,该过程可能需要等待IO资源,导致耗时很长;

  • DDL命令执行到最后阶段被kill,需要删除中间过程的临时文件,也可能受IO资源影响耗时较久。

关于客户端的误解

第一个误解是,如果直接在客户端Ctrl+C,是否可以直接终止线程呢?

答案是不可以的,在客户端的操作只能操作到客户端的线程,而客户端和服务端只能通过网络交互,是不可能直接操作服务端线程的。实际执行Ctrl+C时,是MySQL客户端另外启动一个连接,然后发送一个kill query命令。

第二个误解是,如果库里面的表特别多,连接就会很慢。

很多人会认为是表的数目影响了连接性能,但从第一篇文章就知道,客户端和服务端建立连接的时候,需要做的就是TCP握手、用户校验、获取权限,这些操作跟表的个数无关。实际上,当使用默认参数连接时,MySQL客户端会提供本地库名和表名补全的功能,为实现这个功能,客户端连接成功后,需要多做一些操作:

  • 执行show databases;

  • 切到库执行show tables;

  • 将这两个命令的结果用于构建一个本地的哈希表。

当一个库中表个数非常多,第三步就会花很长时间。因此,感知到的连接过程慢,不是连接慢和服务端慢,而是客户端慢。

这里自动补全效果是在输入库名或表名时,输入前缀,可以使用Tab补全。在连接命令中加上-A,可以关掉这个自动补全功能,因此如果自动补全用得不多,建议关掉。

另外,除了加-A,加-quick(简写-q),也可以跳过这个阶段。

第三个误解,就是关于-quick这个参数。

从字面上看,会觉得这是一个让服务端加速的参数,但实际上设置这个参数可能会降低服务端的性能。

MySQL客户端发送请求后,接收服务端返回结果方式有两种:

  • 一种是本地缓存,即在本地开一片内存,先存结果;

  • 另一种是不缓存,读一个处理一个。

MySQL客户端默认采用第一种,加上-quick后就会使用第二种。此时如果本地处理得慢,就会导致服务端发送结果被阻塞,因此会让服务端变慢。

因此,-quick是让客户端变得更快,而不是让服务端变得更快。

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

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

相关文章

Axure RP 9 Mac 交互原型设计 - 实践

Axure RP 9 Mac 交互原型设计 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monac…

Ceph IO流程分段上传(1)——InitMultipart - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

第9章 Prompt提示词设计 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

详解Spring Boot DevTools - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

深入解析:rook-ceph自定义添加osd流程

深入解析:rook-ceph自定义添加osd流程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mon…

1789:算24

题目 总时间限制: 3000ms 内存限制: 65536kB 描述 给出4个小于10个正整数,你可以使用加减乘除4种运算以及括号把这4个数连接起来得到一个表达式。现在的问题是,是否存在一种方式使得得到的表达式的结果等于24。 这里…

Proxy 库解析(二)

refl meta template <bool IsDirect, class R> struct refl_meta {template <class P>requires(IsDirect)constexpr explicit refl_meta(std::in_place_type_t<P>): reflector(std::in_place_type&l…

【Python3教程】Python3高级篇之JSON材料解析

【Python3教程】Python3高级篇之JSON材料解析2025-09-20 18:04 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: b…

大模型服务之下的新旧政务智能系统比较 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

流行的 3D 文件格式及其用途指南

了解 3D 文件格式的重要性 三维 (3D) 技术的市场既广泛又复杂,应用范围从电影后期制作和产品原型制作到虚拟现实 (VR) 和增强现实 (AR) 游戏。该技术各种用例不可或缺的一部分是 3D 文件格式,它决定了 3D 数据…

CentOS7.9上安装MySQL8.4

CentOS 7 已在 2024 年 6 月 30 日结束生命周期 (EOL),官方源已停止维护! CentOS 7 已在 2024 年 6 月 30 日结束生命周期 (EOL),官方源已停止维护! CentOS 7 已在 2024 年 6 月 30 日结束生命周期 (EOL),官方源已…

铁头山羊stm32-HAL库 - 实践

铁头山羊stm32-HAL库 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco",…

IDEA编译Maven任务后target目录没有class

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025CSP-S初赛游记

哈哈,在致知楼(逆天诡异滏阳楼)考的。

JBoltAI框架:企业级AI开发的革新路径与行业实践 - 那年-冬季

JBoltAI框架:企业级AI开发的革新路径与行业实践在人工智能与产业深度融合的当下,企业级AI开发框架正成为推动智能化转型的关键基础设施。JBoltAI作为面向Java技术生态的智能开发框架,通过模块化架构设计与多模型适配…

JBoltAI:重塑视频创作,开启零门槛智能混剪新时代 - 那年-冬季

JBoltAI:重塑视频创作,开启零门槛智能混剪新时代在当今这个视觉内容占据主导地位的时代,视频已成为信息传递、品牌宣传和创意表达的重要载体。然而,传统的视频制作过程往往伴随着高昂的专业门槛、漫长的时间投入以…

深入解析:手搓一个 DELL EMC Unity存储系统健康检查清单

深入解析:手搓一个 DELL EMC Unity存储系统健康检查清单pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas…

实用指南:Spring Boot 读取 YAML 配置文件

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

完整教程:AVL树(平衡二叉搜索树)

完整教程:AVL树(平衡二叉搜索树)2025-09-20 17:48 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !imp…

Vscode + Latex指南

引言 Overleaf编译大项目的时候总是失败,这时候就需要用到本地的latex了。 本地方案已经比较成熟,只是需要一点配置。 vscode安装一个扩展即可需要关闭拼写检查 打开设置-扩展-Latex加入一行"latex.linter.enab…