• 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指的时加速客户端的目的,此时客户端放弃为请求结果使用本地缓存的策略,而是不缓存,读一个处理一个,这样反而会影响服务端的吞吐量。

  • 相关阅读:
    Python爬虫IP代理教程,让你不再为IP被封禁发愁
    一个值只有0和1的字段,到底要不要建索引.一个表只有一个字段,用不用索引
    SciVal
    除了article 和 review,还有哪些论文类型
    windows7/10文件夹中搜索指定大小的文件
    国内外大学IP地址段
    教你如何用proxyhunter找大学代理
    SCI JCR ESI等名词解释
    solr全文检索实现原理
    设计一个回调要注意哪些事情
  • 原文地址:https://www.cnblogs.com/linyihai/p/16156349.html
Copyright © 2020-2023  润新知