在MySQL中,kill命令分为如下两种:
1、kill query + pid
2、kill connection + pid 其中connection可以省略
先来说说这俩语法的概念,第一种kill query pid指的是断开当前线程中正在执行的语句,而不断开线程连接。第二种kill pid的方法指的是断开该线程的连接,如果线程中有正在执行的语句,那么也会停止这个语句。
当收到kill query 的命令后,MySQL将会执行哪些动作?
可以肯定的是,不会直接kill线程,因为如果直接kill掉的话,如果该线程中还持有元数据的MDL锁,那么这个锁就没有办法释放了,实际上,kill query的命令会执行如下的动作:
1、首先将session的运行状态改为THD:KILL_QUERY
2、向session的执行线程发送一个终止信号。发送终止信号的目的,就是为了让线程去处理THD:KILL_QUERY的运行状态。
上述例子,都是在某个线程可以被kill命令“唤醒”的场景下进行的,在某些场景下,kill query pid的方法不能停止一个线程,原因是当前线程处于一种无法被"唤醒"的
状态,例如下面这种情况:
情况一:
当我们把参数 innodb_thread_concurrency设置为2,以为这同时只能有2个线程并发,此时我们开3个会话窗口,在第3个会话上执行select语句,然后kill它,你会发现出现如下的场景:
---------会话1--------
mysql> select sleep(100) from test0;
---------会话2--------
mysql> select sleep(100) from test0;
---------会话3--------
mysql> select * from test0;
卡主
---------会话4--------
mysql> show processlist;
+----+------+-----------------+------+---------+------+--------------+------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------------+------+---------+------+--------------+------------------------------+
| 2 | root | localhost:51886 | test | Query | 113 | User sleep | select sleep(100) from test0 |
| 3 | root | localhost:51898 | test | Query | 61 | User sleep | select sleep(100) from test0 |
| 4 | root | localhost:51920 | test | Query | 32 | Sending data | select * from test0 |
| 6 | root | localhost:51941 | NULL | Query | 0 | starting | show processlist |
+----+------+-----------------+------+---------+------+--------------+------------------------------+
4 rows in set (0.00 sec)
mysql> kill query 4;
Query OK, 0 rows affected (0.00 sec)
---------会话3--------
mysql> select * from test0;
卡主
---------会话4--------
mysql> show processlist;
+----+------+-----------------+------+---------+------+--------------+------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------------+------+---------+------+--------------+------------------------------+
| 2 | root | localhost:51886 | test | Query | 132 | User sleep | select sleep(100) from test0 |
| 3 | root | localhost:51898 | test | Query | 80 | User sleep | select sleep(100) from test0 |
| 4 | root | localhost:51920 | test | Killed | 51 | Sending data | select * from test0 |
| 6 | root | localhost:51941 | NULL | Query | 0 | starting | show processlist |
+----+------+-----------------+------+---------+------+--------------+------------------------------+
4 rows in set (0.00 sec)
mysql> kill 4;
Query OK, 0 rows affected (0.00 sec)
---------会话3--------
ERROR 2013 (HY000): Lost connection to MySQL server during query
可以看到,当执行kill 4的时候,会话3的连接才断开,在执行kill 4的时候,MySQL做了如下几个动作:
1、 将线程状态置为kill_connection
2、关闭线程的网络连接。
在MySQL中,如果一个线程的状态是KILL_CONNECTION,就把Command列显示Killed。
情况二:
除了上述这种场景外,在一些读写IO压力比较大的场景下,由于IO一直不能返回,也会导致MySQL不能及时判断线程的状态,从而造成kill之后,语句无法停止的现象。
情况三:
各类大事务、大查询、DDL等情况。
如果对大事务执行期间进行kill操作,则会利用undo log进行大量的回滚,可能造成很长的耗时,
或者大查询的回滚,如果在查询途中产生了大量的临时文件,此时需要删除文件,造成IO资源争用。
DDL操作执行到最后,如果接受了kill命令,则需要删除之间过程的临时文件,也可能造成IO资源争用。
在一些客户端上,当我们发现输入错误之后,往往会使用ctrl + c的命令去终止当前操作,本质上ctrl + c 指令其实是相当于在另外的session中,执行了一个kill query pid的指令。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有