【MySQL】デッドロックしているプロセスをkillする
はじめに
生きてるとたまーにデッドロックに遭遇することありますよね。
トランザクションの貼り方がいけてない、というか考慮されてない、というかよくわからず処理全体をトランザクションで覆っただろおまえ!みたいなアプリケーションのせいで。
そんなときサクッとプロセス削除できるようにメモ。
MySQLでデッドロックの原因となっているクエリをkillする
原因のプロセスを探す
show processlist;
Idを指定してkill
kill 1234567;
以上、簡単ですね。
デッドロックとは?
そもそもデッドロックって何?何で起きるの?という人向けに簡単な例を。
usersテーブルの例
usersテーブルがあったとします。
mysql> select * from users; +----+---------+ | id | name | +----+---------+ | 1 | aoki | | 2 | iida | | 3 | ueda | | 4 | enomoto | | 5 | okada | | 6 | tanaka | | 7 | yamada | +----+---------+
ある日、Aさんがレコードを1→2→3の順に削除していました。
start transaction; delete from users where id = 1; delete from users where id = 2; delete from users where id = 3;
時を同じくして、Bさんが5→4→3の順に削除しています。
start transaction; delete from users where id = 5; delete from users where id = 4; delete from users where id = 3;
するとどうでしょう。Aさんがすでにid=3のレコードをいじっていたため応答が返ってきません。 Bさんは立ち尽くします。
そんなことも知らずAさんは4のレコードを削除しようとしました。
delete from users where id = 4;
するとどうでしょう。Bさんがすでにid=4のレコードをいじっていたため応答が返ってきません。 Aさんは立ち尽くします。
AさんBさんの二人はそのままいつまでも途方に暮れていましたとさ。。。
これがデッドロック!!!!!
ちなみに
- デッドロック中にCさんがid=6,7のレコードを削除することは可能
- MySQLのInnoDBはデッドロックを自動で検出し片方をロールバックしてくれる機能があります。
- Aさんがid=4のレコードを処理したタイミングでBさんがrollbackされます
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
って言われる
- MySQLのMyISAMはそもそもトランザクションがないから気をつけろ!
さいごに
処理の途中でDBとのコネクション切れちゃった時にデータの整合性がとれなくなっちゃうー!って部分をトランザクションで囲みましょう。
切れても問題なしってところはトランザクション分けれるポイントですね。