MySQL といえば、スケーリングが容易なオープンソース RDBMSとして有名ですね。
そのMySQLですが、高負荷環境においてレプリケーション遅延やほげほげな理由で、Sessionが貯まりすぎて、止む無く Select系のセッションのみkill必要に迫られる場合があります。
そんな時、数百以上あるSession をサクッとKillするクエリを生成したい。
そこで、PowerShellです。
サクッと書いて、SQLを生成、クリップボードに転送、実行できちゃいます。
思いついてからじっこうんまでの手軽さ、堅実性、柔軟性は使ってて快適です。
単純に kill SessionID の形式です。
SessionID は show full processlist の結果から取得できます。
show full processlist などのコマンド結果は HeidiSQLなどで、簡単にcsvで取得可能です。
作ってみよう
まず、csvは、適当なファイルに置いておくとしましょう。
このような形式です。
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
processlist.txt と命名しました。
そして、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
全文
こんなざっくりで。
$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
簡単ですね。便利に使えればいいと思います。
ご覧のとおり、 pipeline に条件を加えたり削除するだけなので柔軟に書けるし簡単です。
使い慣れていればなんでもいいと思います。
別にbashでも同程度の時間で書けますし。
でもここまで条件を簡単にかけるかというと、PowerShellが楽と感じるのはひいき目なんでしょうね(
Code Sample
GitHubにおいておきます。
https://github.com/guitarrapc/PowerShellUtil/blob/master/PS-MySQLConnect/CreateKillSessionQuery.ps1