mysql> show processlist; +----+------+------------------+------+---------+------+-------------------------+--------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+------------------+------+---------+------+-------------------------+--------------------------------------+ | 2 | root | 172.28.0.1:45180 | test | Query | 13 | updating | update test set id = 2 where id = 10 | | 3 | root | 172.28.0.1:45184 | test | Query | 12 | Waiting for table flush | flush tables | | 4 | root | 172.28.0.1:45188 | test | Query | 10 | Waiting for table flush | select * from test | | 6 | root | 172.28.0.1:45196 | NULL | Query | 0 | starting | show processlist | +----+------+------------------+------+---------+------+-------------------------+--------------------------------------+
mysqldumpで遊んでいたらFLUSH TABLESで刺さっていたので調べてみた。
どうやったら起きるのか
- TxAでレコードを1をアップデート
- TxBでレコードを1をアップデート、ロック待ち
- TxCでFLUSH TABLESを実行。Waiting for table flushでTxBの処理待ちとなる
調べてみたらどうやらMySQLの仕様のようでmetadataロックのようなロックを内部で撮っている模様。ロックwaitを短くするなどで対応しましょうという感じ。デッドロック検出の機構が動かないのはちょっと罠だなと思いました。