tech.guitarrapc.cóm

Technical updates

PowerShell で MySQL の kill sessionid を Show Full Processlist から生成してみる

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