MySQL 执行Kill命令后,执行命令为啥没马上停止?

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

kill 命令

MySQL 提供了 kill query + 线程 id 和 kill [connection] + 线程id 两种停止执行命令的指令。
kill connection 中的 connection 可以省略。

kill connection 命令执行过程:
1、把线程状态设置为KILL_CONNECTION
2、关闭请求线程的网络连接。此时show processlist的显示结果为Killed。主要原因是如果一个线程的状态是KILL_CONNECTION, 就把Command列显示成Killed。

kill connection 先把客户端的sql连接断开,后续执行流程走kill query

kill 命令的运行原理

将执行线程的运行状态改成THD::KILL_QUERY状态,并向执行线程发一个信号,这个信号有点像 我们用kill -9 向操作系统发送终止信号。

另外kill connection 会断开网络连接,然后客户端会重新在一个线程发送kill query命令,show processlist会将kill connection的状态显示为Killed。然而其实innodb 可能因为io繁忙,锁等待,并发线程数不够,而没有机会终止当前线程。出现这种情况,及时腾出系统资源,比如IO,终止掉其他线程,增大innodb_thread_concurrency, 然后等待线程执行完毕。
总而言之可以分成两大类:

  • 线程没有执行到判断线程状态的逻辑
  • 终止逻辑耗时太长:
  • kill超大事务,回滚时需要回收事务期间生成的数据包版本,耗时很长;
  • DDL命令执行到最后阶段,如果被kill, 需要删除中间过程的临时文件,也可能受IO资源影响耗时较久。
  • 大查询回滚,如果查询过程中生成了比较大的临时文件,加上此时文件系统压力大,删除临时文件可能需要等待IO资源,导致耗时较长。

这也是碰到一个被Killed事务一直处于回滚状态时,此时重启MySQL线程也没用,重启后事务还是会回滚。

其他

如果数据集的表很多,比如6万多表,客户端连接上去时,需要初始化本地资源,用来支持命令行不全表名,这个时候可以通过 -A 参数略过。

另外--quick 可以达跳过自动补全功能,quick指的时加速客户端的目的,此时客户端放弃为请求结果使用本地缓存的策略,而是不缓存,读一个处理一个,这样反而会影响服务端的吞吐量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值