あまりにも処理に時間がかかるようなSQLを実行してしまい、MySQLがうんともすんとも言わなくなってしまうような状況、よくありますよね。っていうか、まぁそんな状況あってはならないんですが、時たまあります。そんな時、問題となっているクエリの処理を止めたいわけです。

特定のクエリを止める方法

MySQLで実行中のクエリ一覧を見て、SQLを強制終了する方法

こちらを見てもらえればやり方は分かります。単純にMySQLに入って、show processlist;で問題のあるクエリを発見し、プロセスIDを kill するだけ。とても簡単。

複数のクエリを一括で止める方法

今回は問題のあるクエリが100個あったらどうする…?的なのを解決するエントリーです。まぁ、問題あるクエリ100個ある状況は、アプリ的に問題あるんじゃね?っていうレベルですが。

1個ずつプロセスIDをコピペして…なんてやってられないですよね。まとめてkillしちゃいたい。実は、show full processlistは以下のSQLと同じ。

SELECT * FROM information_schema.PROCESSLIST;

ということは、普通にwhere句などで条件が指定できる。

処理時間に60秒以上かかっているのを表示

SELECT * FROM information_schema.PROCESSLIST WHERE TIME > 59;

ということは、IDも1行にまとめられる。

SELECT GROUP_CONCAT(ID) FROM information_schema.PROCESSLIST WHERE TIME > 59;
+------------------+
| group_concat(ID) |
+------------------+
| 1,2,3,4,5             |
+------------------+

GROUP_CONCAT()関数を使うことで、複数レコードをカンマ区切りの1行にまとめられます。こいつはいいぜ。

複数のプロセスIDをkillする

あとは、こいつをkillすれば良いだけなんですが、MySQL内のkillコマンドでは複数IDを受け付けてくれません。

kill 1,2,3; # これは駄目

というわけで、いったんMySQLから抜けて、普通のコンソールからmysqladminコマンドを使用します。mysqladminのkillはカンマ区切りで複数のIDを受け付けてくれます。心が広い。

$ mysqladmin kill 1,2,3 -h localhost -u hoge

汚物は消毒だ~っ!!ばりのノリで殺してくれます。これでいっときの安寧が訪れますが、そもそもの原因となっているSQLやアプリケーションを修正しないと駄目ですね。はい。