MySQLといえば、スケーリングが容易なオープンソースRDBMSとして有名です。 そのMySQLですが、高負荷環境においてレプリケーション遅延や他理由で、セッションがたまりすぎて、やむを得ずSelect系のセッションのみkill必要に迫られる場合があります。
そんな時数百以上あるセッションをサクッとキルするクエリをPowerShellで生成してみましょう。
サクッと書いて、SQLを生成、クリップボードに転送、実行できます。思いついてから実行までの手軽さ、堅実性、柔軟性は使ってて快適です。
生成方法
kill SessionIDの形式でいいでしょう。SessionIDはshow full processlistの結果から取得できます。
show full processlistコマンド結果はHeidiSQLを使うと、簡単にcsvで取得できます。
作ってみよう
guitarrapc/PowerShellUtil - PS-MySQLConnect/CreateKillSessionQuery.ps1 | GitHub
ご覧のとおり、 pipelineに条件を加えたり削除するだけなので柔軟に書けるし簡単です。 Bashでもいいのですが、PowerShellだと条件を簡単にかけて楽と感じます。
$ImportCSV = "processlist.txt" $csv = Import-Csv -Path .\$ImportCSV $ExcludeUser = "adminUser" $ExcludeIP = "10.0.0.100" $KillQueryType = "select*" $sql = $csv | where User -ne $ExcludeUser | where Host -ne $ExcludeIP | where Info -like $KillQueryType | %{"kill " + $_.id + ";"} $sql | clip
解説
取得したcsvは、processlist.txtに置きます。
Id,User,Host,db,Command,Time,State,Info 205722733,hogeUser,10.0.0.149:38189,hogetable,Query,1813,Sending data,SELECT `id` FROM `hogetable` AS `hoge` WHERE `login` = '2013-07-03 23:59:59',15 205722799,adminUser,10.0.0.227:38591,hogetable,Query,1814,Sending data,SELECT `id` FROM `hogetable` AS `hoge` WHERE `login` = '2013-07-03 23:59:59',15
PowerShellで読み込んで、処理します。 ヘッダーが付いているので、 -headerは不要、またencodingはdefault (sjis) としています。
$ImportCSV = "processlist.txt" $csv = Import-Csv -Path .\$ImportCSV
次に除外する条件として、App Serverからの接続に利用するユーザーのみとします。
$ExcludeUser = "adminUser" $csv | where User -ne $ExcludeUser
更に、除外する条件として、Manege専用サーバーを除くApp Serverからのクエリのみを対象としてます。 特定の管理サーバーからのIPは除くものとします。
$ExcludeIP = "10.0.0.100" $csv | where User -ne $ExcludeUser | where Host -ne $ExcludeIP
さらに、 KillQueryは、 InsertやUpdateなど更新系にかかると致命的なデータ非整合性を招きかねません。 そこで、select文のみ対象とします。
$KillQueryType = "select*" $csv | where User -ne $ExcludeUser | where Host -ne $ExcludeIP | where Info -like $KillQueryType
最後に、idの頭にkillを付けてsqlを生成します。
$csv | where User -ne $ExcludeUser | where Host -ne $ExcludeIP | where Info -like $KillQueryType | %{"kill " + $_.id + ";"}
クリップボードに出力して完成。
$sql = $csv | where User -ne $ExcludeUser | where Host -ne $ExcludeIP | where Info -like $KillQueryType | %{"kill " + $_.id + ";"} $sql | clip