如何停止正在运行的MySQL查询?

309

我通过Linux shell连接到mysql。偶尔会运行一些非常耗时的SELECT查询,它会一直打印输出,我已经知道这不是我想要的结果了,我想停止这个查询。

按下Ctrl+C(多次)会完全终止mysql并带我回到shell,所以我必须重新连接。

有没有可能在不终止mysql本身的情况下停止一个查询?


3
值得一提的是,MySQL 5.7支持服务器端SELECT语句超时。更多信息请参见:http://mysqlserverteam.com/server-side-select-statement-timeouts/ - Morgan Tocker
@MorganTocker提到的文章已经移动到https://dev.mysql.com/blog-archive/server-side-select-statement-timeouts/。 - undefined
7个回答

542
mysql> show processlist;
+----+------+-----------+-----+---------+------+---------------------+------------------------------+----------+
| Id | User | Host      | db  | Command | Time | State               | Info                         | Progress |
+----+------+-----------+-----+---------+------+---------------------+------------------------------+----------+
| 14 | usr1 | localhost | db1 | Query   |    0 | starting            | show processlist             |    0.000 |
| 16 | usr1 | localhost | db1 | Query   |   94 | Creating sort index | SELECT  `tbl1`.* FROM `tbl1` |    0.000 |
+----+------+-----------+-----+---------+------+---------------------+------------------------------+----------+
2 rows in set (0.000 sec)

mysql> kill 16;
Query OK, 0 rows affected (0.004 sec)

mysql> show processlist;
+----+------+-----------+-----+---------+------+----------+------------------+----------+
| Id | User | Host      | db  | Command | Time | State    | Info             | Progress |
+----+------+-----------+-----+---------+------+----------+------------------+----------+
| 14 | usr1 | localhost | db1 | Query   |    0 | starting | show processlist |    0.000 |
+----+------+-----------+-----+---------+------+----------+------------------+----------+
1 row in set (0.000 sec)

10
但是 mysql 正在输出... 我看不到提示符。 - David B
41
我同意这个基本方法,但我认为在这种情况下使用 KILL QUERY 相对于 KILL 稍微更好一些。这样可以终止查询,但不会终止连接。 - Ike Walker
3
如果你的进程列表超出了缓冲区而无法显示完整,一个有用的提示是设置分页器。只需在提示符输入“\P more”。关于此提示的更多信息,请参见http://www.dbasquare.com/2012/03/28/how-to-work-with-a-long-process-list-in-mysql/。 - Scott
@Zilverdistel 你在 phpMyAdmin 中怎么做? - BadHorsie
4
如果在AWS RDS上使用MySQL,您将无法运行KILL命令,但是您可以运行以下命令:CALL mysql.rds_kill(12345) - Kip
显示剩余4条评论

81

只是要补充一下

KILL QUERY **Id** 其中 Id 是从 show processlist 获取的连接 id,如果您不想通常在某些应用程序中杀死连接,则更可取。

有关更多详细信息,请阅读mysql文档此处


我有一个与此相关的问题,连接只是重新生成还是杀死连接最终会导致池大小对应用程序运行过于小? - Uncle Iroh

51

连接到mysql

mysql -uusername -p  -hhostname

显示完整进程列表:

mysql> show full processlist;
+---------+--------+-------------------+---------+---------+------+-------+------------------+
| Id      | User   | Host              | db      | Command | Time | State | Info             |
+---------+--------+-------------------+---------+---------+------+-------+------------------+
| 9255451 | logreg | dmin001.ops:37651 | logdata | Query   |    0 | NULL  | show processlist |
+---------+--------+-------------------+---------+---------+------+-------+------------------+

杀死指定的查询。这里id=9255451

mysql> kill 9255451;

如果您收到权限被拒绝的错误,请尝试以下 SQL 语句:

CALL mysql.rds_kill(9255451)

14
注意:如果使用AWS RDS实例,则需要执行上述最后一个查询。 - Kip

15

使用mysqladmin来终止运行失控的查询:

运行以下命令:

mysqladmin -uusername -ppassword pr

然后记下进程ID。

mysqladmin -uusername -ppassword kill pid

跑偏的查询不应再消耗资源。


9
如果您有mysqladmin,您可以使用以下命令获取查询列表:
> mysqladmin -uUSERNAME -pPASSWORD pr

+-----+------+-----------------+--------+---------+------+--------------+------------------+
| Id  | User | Host            | db     | Command | Time | State        | Info             |
+-----+------+-----------------+--------+---------+------+--------------+------------------+
| 137 | beet | localhost:53535 | people | Query   | 292  | Sending data | DELETE FROM      |
| 145 | root | localhost:55745 |        | Query   | 0    |              | show processlist |
+-----+------+-----------------+--------+---------+------+--------------+------------------+

然后,您可以停止托管长时间运行查询的mysql进程:

> mysqladmin -uUSERNAME -pPASSWORD kill 137

9

您需要运行以下命令来结束进程。 通过查找要终止的进程的ID来确定。

> show processlist;

从id列中获取值并执行以下命令。
kill query <processId>;

查询参数指定我们需要终止查询命令进程。

杀死进程的语法如下:

KILL [CONNECTION | QUERY] processlist_id

参考此链接获取更多信息。


1
这个问题的提出者提到通常只有在MySQL打印输出后才意识到执行了错误的查询。如注所述,在这种情况下,Ctrl-C无法帮助。但是我注意到如果你在任何输出被打印之前捕捉到它,它会中止当前的查询。例如:
mysql> select * from jos_users, jos_comprofiler;

MySQL正在忙于生成上述两个表的笛卡尔积,您很快就会注意到MySQL没有向屏幕输出任何内容(进程状态为Sending data),因此您键入Ctrl-C

Ctrl-C -- sending "KILL QUERY 113240" to server ...
Ctrl-C -- query aborted.
ERROR 1317 (70100): Query execution was interrupted

Ctrl-C同样可用于停止UPDATE查询。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接