笔记 笔记
首页
  • 开发工具
  • Java Web
  • Java 进阶
  • 容器化技术
  • Java 专栏

    • Java 核心技术面试精讲
    • Java 业务开发常见错误 100 例
  • 数据库专栏

    • MySQL 实战 45 讲
    • Redis 核心技术与实战
  • 安全专栏

    • OAuth 2.0 实战课
  • 计算机系统
  • 程序设计语言
  • 数据结构
  • 知识产权
  • 数据库
  • 面向对象
  • UML
  • 设计模式
  • 操作系统
  • 结构化开发
  • 软件工程
  • 计算机网络
  • 上午题错题
在线工具 (opens new window)

EasT-Duan

Java 开发
首页
  • 开发工具
  • Java Web
  • Java 进阶
  • 容器化技术
  • Java 专栏

    • Java 核心技术面试精讲
    • Java 业务开发常见错误 100 例
  • 数据库专栏

    • MySQL 实战 45 讲
    • Redis 核心技术与实战
  • 安全专栏

    • OAuth 2.0 实战课
  • 计算机系统
  • 程序设计语言
  • 数据结构
  • 知识产权
  • 数据库
  • 面向对象
  • UML
  • 设计模式
  • 操作系统
  • 结构化开发
  • 软件工程
  • 计算机网络
  • 上午题错题
在线工具 (opens new window)

购买兑换码请添加

添加时候请写好备注,否则无法通过。

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

    • Kill 命令
      • 收到Kill后线程做什么?
        • 另外两个关于客户端的误解
        EasT-Duan
        2024-03-29
        随笔
        目录

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

        欢迎来到我的 ChatGPT 中转站,极具性价比,为付费不方便的朋友提供便利,有需求的可以添加左侧 QQ 二维码,另外,邀请新用户能获取余额哦!最后说一句,那啥:请自觉遵守《生成式人工智能服务管理暂行办法》。

        正文

        # Kill 命令

        • KILL QUERY 线程 ID:这个命令会终止指定连接 ID 当前正在执行的语句,但是连接本身会保持不变。这意味着,如果一个长时间运行的查询阻塞了你的数据库,你可以使用 KILL QUERY 来只终止那个查询,而不影响到其他的操作。
        • KILL CONNECTION 线程 ID:它会在终止任何该连接正在执行的语句后,终止与给定的 processlist_id 关联的连接。这意味着,不仅当前正在执行的查询会被终止,整个连接也会被关闭。

        # 收到 Kill 后线程做什么?

        Session A Session B Session C
        begin;
        update t set c=c+1 where id =1 ;
        update t set c=c+1 where id =1 ; // blocking
        ERROR Query execution was interrupter kill query thread_id_X;

        当对一个表进行增删改查操作时,会在表上加一个 DML 读锁,如果说执行了 kill 就直接杀死的话,这个 MDL 的读锁就无法释放了。

        所以 Kill 不是立刻停止的意思,而是这个语句已经不需要执行继续执行了,就相当于一个信号。MySQL 里的 kill 执行做了两件事

        1. 把 B 的运行状态改成了 THD::KILL_QUERY,即将变量 killed 设置为 THD::KILL_QUERY。
        2. 给 B 的执行线程发一个信号,将其从阻塞状态唤醒,然后检查 killed 如果为 THD::KILL_QUERY,停止查询当前操作。

        发信号的目的是,让线程退出等待来处理 THD::KILL_QUERY 的状态。这个过程中有多处埋点,在埋点处处理 THD::KILL_QUERY 状态,如果处于等待状态,必须是一个可以被唤醒的线程,否则根本不会执行到埋点处。

        kill 不了的例子

        1. 线程没有执行到判断自己状态的逻辑。
        2. 终止逻辑耗时较长。

        案例一

        首先设置并发线程为 2,set global innodb_thread_concurrency=2。

        Session A Session B Session C Session D Session E
        select sleep(100) from t; select sleep(100) from t;
        select * from t ;// blocking
        kill query C
        kill C
        ERROR LOST Connection....

        通过 show processlist 查看,这个命令还在执行,但是状态变成了 killed。

        一个线程在等行锁的过程中使用 pthread_cond_timedwait 参数,表示的是每 10 毫秒进行一个判断看是否可以进入执行状态,如果不行就调用 nanosleep 进入 sleep 状态。虽然执行了 kill query 但是在循环过程中并没有判断状态。

        而 kill connection 则是,先把状态设置为 KILL_CONNECTION 然后关掉线程的网络连接,所以这个时候出现了 LOST connection 的字样。show processlist 有个特性为:如果一个线程的状态是 KILL_CONNECTION,就把 Command 列显示成 Killed。

        所以即便是客户端退出了,线程依旧是在等待中,因为它在等待状态,没有机会检查其状态并发现它已经被杀死了。

        案例二

        • 超大事务执行期间被 kill。这个时候回滚操作需要对所有的产生的数据进行回收。耗时很长。
        • 大查询回滚。查询过程中生成了较大的临时文件,加上 IO 资源紧张,删除临时文件需要等待 IO。
        • DDL 命令执行到最后阶段,如果被 kill,需要删除中间过程的临时文件,也可能受 IO 资源影响耗时较久。

        笔记

        MySQL 在以下情况下可能会生成临时文件:

        1. 排序操作:当你执行一个包含 ORDER BY 子句的查询时,如果排序的结果集不能被完全放入内存中,MySQL 会使用临时文件来帮助完成排序操作。

        2. 分组操作:类似地,当你执行一个包含 GROUP BY 子句的查询时,如果分组的结果集不能被完全放入内存中,MySQL 也会使用临时文件来帮助完成分组操作。

        3. 联接操作:当你执行一个大型的联接操作时,MySQL 可能会使用临时文件来存储联接的中间结果。

        4. 子查询或派生表:MySQL 在处理子查询或派生表时,可能会使用临时文件来存储中间结果。

        5. UNION 操作:当你执行一个 UNION 操作时,MySQL 可能会使用临时文件来存储 UNION 的结果。

        6. 大型的 INSERT...SELECT 操作:当你执行一个大型的 INSERT...SELECT 操作时,MySQL 可能会使用临时文件来存储 SELECT 的结果。

        # 另外两个关于客户端的误解

        mysql -uroot -p123456 db1
        
        1
        1. 如果库里的表很多,连接就会很慢。因为在测试时候也会发现,如果一个库里有比如 6 万张表那么连接速度很慢,如果很少就很快。
          • 但是每个客户端在和服务端建立连接的时候,需要做的事情就是 TCP 握手、用户校验、获取权限。但这几个操作,显然跟库里面表的个数无关。
          • 因为在默认连接的时候,MySQL 客户端会提供一个本地库名和表名补全的功能。需要多做一些操作。
            • show databases;
            • use db1;
            • show tables;
            • 将上面的命令构建到一个本地 hash 表中,用来做 tab 键补全。
          • 所以会发现库多了连接就慢了。
          • 如果加上一个参数 -A 会关闭这个补全功能,就会快很多。

        注意

        除了加 -A 以外,加–quick (或者简写为 -q) 参数,也可以跳过这个阶段。但是,这个–quick 是一个更容易引起误会的参数,也是关于客户端常见的一个误解。但实际上恰恰相反,设置了这个参数可能会降低服务端的性能。

        一旦使用了 - q 就会使用到 mysql_use_result 方式这个方式就是说读一行向客户端发送一行,如果说客户端处理的慢了。那么就会导致服务端处理被阻塞。

        1. mysql_store_result 需要申请本地内存来缓存查询结果,如果查询结果太大,会耗费较多的本地内存,可能会影响客户端本地机器的性能。
        2. 是不会把执行命令记录到本地的命令历史文件。
        #MySQL
        上次更新: 2025/04/12, 07:54:33
        最近更新
        01
        Reactor 核心
        02-24
        02
        前置条件
        10-30
        03
        计算机网络
        09-13
        更多文章>
        Theme by Vdoing | Copyright © 2019-2025 powered by Vdoing
        • 跟随系统
        • 浅色模式
        • 深色模式
        • 阅读模式