TL;DR
yt-mdl-checkerというスクリプトを書いたperformance_schema.metadata_locksからPENDINGになっているEXCLUSIVEなロックを引いて、同じテーブルで既にGRANTEDになっているやつをKILLするスクリプト- クエリ自体は大したことないので、わざわざスクリプト使わなくてもスニペットとして使えるはず
- https://github.com/yoku0825/ytkit/blob/036be21ff0cc56ec8fadc523e2d2ab4e6965f685/lib/Ytkit/MySQLServer.pm#L1159-L1216
- MDLが多すぎて
p_s.metadata_locksの行数が大きくなると追加の負荷になりそうなので注意…
主に「 ALTER TABLE 流したらオンラインALTER TABLEのはずなのに刺さった」対策。たとえ SELECT でも、一度でもそのテーブルに触って COMMIT されていないトランザクションがあれば、その共有MDLが ALTER TABLE の排他MDLをブロックしてしまって、その後のクエリが共有MDLを取れなくなって連鎖的にやられていくケース。
ALTER TABLE 開始時の排他MDLに刺さったらCtrl+Cすればいいだけだけど、オンラインALTER TABLEは一度共有MDLにフォールバックした後 ALTER TABLE 終了処理の中でもう一度排他MDLを取ろうとするので、後者を止めるのは難しい(ずっと張り付いてられるくらいの時間なら張り付いていればいいだけだけれども)ので、なんかALTER TABLEとセットで流せる奴があるといいなとか思った。
使い方は mysql コマンドラインクライアントと似たようなオプションで
$ yt-mdl-checker -hlocalhost -uroot -p'xxx' -i 3 --kill
とかやっておけば、3秒おきにチェックして勝手に KILL してくれそうな感じにしてある。
READMEも書いてます。
https://github.com/yoku0825/ytkit/blob/9b4af50b98b6a16b8f44f084d7220e32a4290c63/README.md#L571-L662
0 件のコメント :
コメントを投稿