当kill在MySQL中遇到不死金身killed怎么办? 最后更新时间:2024年08月07日 ### MySQL kill命令 在使用MySQL中,我们对于执行时间过长的SQL想要放弃的方法就是kill这个SQL。在MySQL中kill有两个命令: ```sql kill [connection |query] processlist_id ``` 其中kill connection 和kill的效果是一样的,会把给定的processlist_id的连接断开;kill query只把当前执行的query终止,但连接不会断开。 ### kill的执行原理: 使用kill命令时只是对给定的THD结构打了一个标记,所以使用kill命令后,需要一段时间才能把对应的processlist_id回收。这里有以下特性需要了解一下:kill标记的检测是每次读完一个Block中的行时,会检测一下是否设置有kill标记: 对select语句,如使用了order by , group by ,当THD遇到kill标记时,在读完当前块中的行后,会立即aborted释放 对于alter table操作,如果在copy table过程中遇到kill标记,该语句在终止读取原表时,会把temporary表删除后aborted退出 对于update,delete操作,如果检测到kill标记,对于非事务操作,直接退出,对于事务操作需要回滚( InnoDB表是事务操作) 对于显式使用locked的情况,遇到kill命令,该THD立即aborted 对于空间满了的情况,kill也不会立即生效,因为被kill的进程需要先把'disk full' 这样的错误信息写到报错日志中。 从理论上看,以上几种情况:select 加order by , group by ; alter table, locked语句时,可以放心的kill这些是绝对没问题的。其它情况kill时,就要掂量一下,下面给大家看一下有killed标识不死金身的问题: ### kill故障还原 select count(*) from xxxx 已经被标识为killed, 过了N久,还没有回收到该processlist_id ![](https://yidaimingjvn.xyz/usr/uploads/2024/08/3711699141.png) 在这个状态下,MySQL其实可以对外提供服务,什么也不影响的。但通过show engine innodb status\G;观察:purge done for trx's n:o 一直卡在了48700628 ![](https://yidaimingjvn.xyz/usr/uploads/2024/08/345853627.png) 第二天观察:purge done for trx's n:0 还是48700628 ![](https://yidaimingjvn.xyz/usr/uploads/2024/08/621398882.png) 观察死锁并行什么,都没问题。 ![](https://yidaimingjvn.xyz/usr/uploads/2024/08/617975861.png) 目前来看MySQL对外服务啥的也没问题,唯一看到的就是purge done for trx's n:o卡着了,从processlist中看看该SQL还在counting records中。 结合该MySQL版本8.0.17,查询MySQL官方的知识库。 ### 新功能InnoDB 并行读 MySQL 8.0.14后引入了innodb_parallel_read_threads这个功能:基于主键读取可以并行读取,默认是4个thread, 8.0.17后对分区表基于主键读取也可以支持并行。借助于MySQL官方Support(收费的)知识库搜索了一下: killed聚焦到8.0的版本看到如下分析: ![](https://yidaimingjvn.xyz/usr/uploads/2024/08/2627788228.png) 从上面可以看出来,这个是一个Bug,确实是基于主键并行读操作造成的。建议升级到8.0.22的版本。如果又不能升级,临时的解决方案是: innodb_paralel_read_threads=1 结合这资料处理方案: 设置:innodb_parallel_read_threads=1 然后重启MySQL解决~~~~ ### 总结: 这个案例,想通过阅读源码,非常难搞定,不好复现。对于好复现的报错,可以通过阅读源码+Debug比较好定位,但这类偶然出现的,还需要借助于专家库[购买企业版]或是bug库,另一方面也要对使用的MySQL版本引入了什么新特性非常了解才容易快速定位问题。 目前来看遇到killed标识的不死金身,最快速的解决办法就是重启MySQL,如果你有特别的办法,也欢迎留言分享一下。 据观察MySQL 8.0.23后的版本非常稳定,MySQL 8.0.25这个版本基本随意使用,如果你还在犹豫MySQL选择那个版本时,可以考虑使用MySQL 8.0.25这个版本。 ### 文章来源: [当kill在MySQL中遇到不死金身killed怎么办?|Vol 16](https://cloud.tencent.com/developer/article/1857161 "当kill在MySQL中遇到不死金身killed怎么办?|Vol 16")
Comments | NOTHING