MySQL 性能低下への対策:pt-kill によるセッション管理
MySQL データベースの運用において、長時間実行されるクエリはリソース枯渇や応答遅延の主要な要因となります。手動でのセッション特定と終了作業は非効率であり、即時対応が困難な場合也多々あります。Percona Toolkit に含まれる pt-kill は、特定の条件に合致する MySQL セッションを自動的に検出し、終了させることができる強力なツールです。本稿では、pt-kill による慢查询(スロークエリ)対策の具体的な運用方法を解説します。
1. 環境構築と権限設定
pt-kill を導入する前に、ツールが MySQL に接続し、必要な操作を実行できる環境を整備する必要があります。
1.1 Percona Toolkit のインストール
pt-kill は Percona Toolkit パッケージに含まれています。OS に応じて以下の手順でインストールを行います。
CentOS / RHEL 環境:
# Percona リポジトリの RPM をダウンロード
wget https://downloads.percona.com/downloads/percona-toolkit/3.5.4/binary/redhat/7/x86_64/percona-toolkit-3.5.4-2.el7.x86_64.rpm
# RPM パッケージをインストール
yum install percona-toolkit-3.5.4-2.el7.x86_64.rpm -y
# インストール確認
pt-kill --version
Ubuntu / Debian 環境:
apt update && apt install percona-toolkit -y
1.2 専用オペレーションユーザーの作成
セキュリティ観点から、root 権限ではなく、必要な権限のみを持った専用ユーザーを作成することを推奨します。ここでは ops_mgr というユーザーを作成します。
-- ユーザー作成(ローカル接続限定)
CREATE USER 'ops_mgr'@'localhost' IDENTIFIED WITH MYSQL_NATIVE_PASSWORD BY 'OpsSecure#99';
-- 必要最小限の権限付与(本番環境では PROCESS と SUPER 程度に制限)
GRANT ALL ON *.* TO 'ops_mgr'@'localhost';
-- 権限の反映
FLUSH PRIVILEGES;
※本番環境では、セッション確認用の PROCESS 権限と、終了用の SUPER 権限のみを付与するのが安全です。
2. pt-kill 主要運用パターン
pt-kill は「条件指定」と「アクション」の組み合わせで動作します。以下の 5 つのパターンは、現場で頻繁に利用される構成例です。
パターン 1:dry-run による条件検証
実際にセッションを終了させる前に、--print オプションを使用して、どのクエリが検出されるか確認します。
要件: 実行時間が 20 秒を超えるセッションを 5 秒間隔で検出し、画面に出力する。
pt-kill \
--user=ops_mgr \
--password='OpsSecure#99' \
--socket=/tmp/mysql.sock \
--busy-time=20 \
--interval=5 \
--print
検証方法: 別ターミナルで select sleep(120); を実行し、pt-kill を実行中のターミナルに該当セッション情報が出力されるか確認します。
パターン 2:対象セッションの強制終了
条件検証が完了したら、--kill を追加して実際にセッションを terminates します。
要件: 20 秒以上実行されているクエリを終了し、ログに出力する。
pt-kill \
--user=ops_mgr \
--password='OpsSecure#99' \
--socket=/tmp/mysql.sock \
--busy-time=20 \
--kill \
--print
対象クエリを実行中のクライアント側では、接続断エラー(ERROR 2013 等)が発生し、処理が中断されます。
パターン 3:バックグラウンド常駐運用
運用環境では、pt-kill をデーモン化して常駐させる必要があります。--daemonize オプションを使用します。
pt-kill \
--user=ops_mgr \
--password='OpsSecure#99' \
--socket=/tmp/mysql.sock \
--busy-time=20 \
--kill \
--print \
--daemonize
プロセス確認は ps -ef | grep pt-kill で行え、停止はプロセス ID を指定して kill コマンドを実行します。
パターン 4:操作ログの記録
どのクエリがいつ終了されたかを追跡できるように、ログファイルへの出力を設定します。
要件: 操作履歴を /var/log/mysql_pt_kill.log に記録する。
pt-kill \
--user=ops_mgr \
--password='OpsSecure#99' \
--socket=/tmp/mysql.sock \
--busy-time=20 \
--kill \
--print \
--daemonize \
--log=/var/log/mysql_pt_kill.log
ログ内容は tail -f /var/log/mysql_pt_kill.log でリアルタイムに監視可能です。
パターン 5:特定ユーザーへのフィルタリング
管理者ユーザーなどの重要セッションを誤って終了させないよう、特定のアプリケーションユーザーのみを対象とします。
手順 1: テスト用ユーザー作成
CREATE USER 'dev_user'@'localhost' IDENTIFIED WITH MYSQL_NATIVE_PASSWORD BY 'DevPass!2024';
GRANT SELECT ON *.* TO 'dev_user'@'localhost';
FLUSH PRIVILEGES;
手順 2: ユーザー指定で pt-kill 実行
pt-kill \
--user=ops_mgr \
--password='OpsSecure#99' \
--socket=/tmp/mysql.sock \
--match-user 'dev_user' \
--busy-time=20 \
--kill \
--print
これにより、root や他のユーザーの長時間クエリは影響を受けず、dev_user のセッションのみが制御対象となります。
3. 主要パラメータリファレンス
運用で頻繁に使用するオプションを以下にまとめます。
| パラメータ | 機能説明 |
|---|---|
--user |
MySQL 接続ユーザー名 |
--password |
接続パスワード(特殊文字を含む場合は quoting 推奨) |
--socket |
ローカル接続時の socket ファイルパス(远程は --host/--port) |
--busy-time=N |
実行時間が N 秒を超えたセッションを対象とする |
--interval=N |
チェック実行間隔(秒) |
--print |
対象セッション情報を標準出力に表示 |
--kill |
対象セッションを終了させる |
--daemonize |
バックグラウンドプロセスとして実行 |
--log=PATH |
操作ログの出力先ファイルパス |
--match-user |
特定の MySQL ユーザーのみをフィルタリング |
--match-db |
特定のデータベース使用中セッションのみをフィルタリング |
4. 運用上の注意点
- 権限管理: 本番環境では、pt-kill 用ユーザーに付与する権限を
PROCESSとSUPERに限定し、セキュリティリスクを低減してください。 - 閾値の調整:
--busy-timeの値はシステム特性に合わせて設定します。OLTP 系では短め(5〜10 秒)、分析系(OLAP)では長め(30 秒以上)にするなど、業務影響を考慮する必要があります。 - 監視体制:
--logを活用し、ログ収集システムと連携させることで、誰のどのクエリが殺されたかを追跡可能にします。また、systemd 等を用いてプロセスの自動再起動構成を推奨します。 - 事前検証: 本番投入前に必ず
--printのみで動作させ、意図しないセッションが検出されないか確認してください。