MySQL の SHOW PROCESSLIST で実行中クエリを監視する
SHOW PROCESSLIST は、MySQL サーバーで現在実行中のスレッドを一覧表示するコマンドです。遅いクエリの特定、ロック待ちの調査、負荷状況の把握に役立ちます。
基本的な使い方
SHOW PROCESSLIST;デフォルトでは Info 列(実行中のクエリ)が 100 文字で切り詰められます。完全なクエリを見るには FULL を付けます。
SHOW FULL PROCESSLIST;出力の見方
| 列 | 意味 |
|---|---|
| Id | 接続 ID(KILL で使用) |
| User | 接続ユーザー |
| Host | 接続元ホスト |
| db | 使用中のデータベース |
| Command | 実行中のコマンドタイプ |
| Time | 現在の状態の経過秒数 |
| State | スレッドの状態 |
| Info | 実行中の SQL(NULL の場合もあり) |
Command 列の主な値
SQL クエリを実行中。Info 列に実際のクエリが表示されます。
クライアントからの次のコマンドを待機中。アイドル状態です。
レプリカがソースに接続中、または接続処理中。
KILL コマンドで終了を指示されたが、まだ終了していない状態。
State 列の重要なパターン
State 列はクエリ実行のどの段階にいるかを示します。問題を示唆するものを覚えておきましょう。
| State | 意味 | 注意点 |
|---|---|---|
| Sending data | クエリ結果を読み取り中 | 長時間続くと問題 |
| Waiting for table metadata lock | DDL 待ち | ALTER TABLE がブロックされている可能性 |
| Copying to tmp table | 一時テーブルにコピー中 | 大量データで発生 |
| Sorting result | ソート処理中 | filesort が発生 |
| Locked | テーブルロック待ち | MyISAM で発生しやすい |
問題のあるクエリを見つける
長時間実行中のクエリを見つけるには、Time 列でフィルタします。
SELECT * FROM information_schema.PROCESSLIST
WHERE Command = 'Query' AND Time > 10
ORDER BY Time DESC;これで 10 秒以上実行中のクエリが見つかります。
performance_schema を使う方法
より詳細な情報が必要な場合は、performance_schema を使います。
SELECT
THREAD_ID,
PROCESSLIST_USER,
PROCESSLIST_HOST,
PROCESSLIST_DB,
PROCESSLIST_COMMAND,
PROCESSLIST_TIME,
PROCESSLIST_STATE,
PROCESSLIST_INFO
FROM performance_schema.threads
WHERE PROCESSLIST_COMMAND = 'Query';問題のあるクエリを停止する
特定のクエリを強制終了するには KILL コマンドを使います。
-- 接続を終了(クエリ + 接続)
KILL 12345;
-- クエリだけを終了(接続は維持)
KILL QUERY 12345;12345 は SHOW PROCESSLIST で確認した Id です。
ロック待ちの調査
Waiting for table metadata lock などが表示されている場合、何がロックを保持しているか調べます。
SELECT
r.trx_id AS waiting_trx_id,
r.trx_mysql_thread_id AS waiting_thread,
r.trx_query AS waiting_query,
b.trx_id AS blocking_trx_id,
b.trx_mysql_thread_id AS blocking_thread,
b.trx_query AS blocking_query
FROM information_schema.innodb_lock_waits w
JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id
JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id;MySQL 8.0 以降では、performance_schema.data_lock_waits を使います。
Sleep 接続の監視
Sleep 状態の接続が多すぎると、max_connections を圧迫します。
SELECT COUNT(*) AS sleep_count
FROM information_schema.PROCESSLIST
WHERE Command = 'Sleep';長時間 Sleep している接続は、wait_timeout の設定で自動切断するか、アプリケーション側のコネクションプールを見直します。
継続的な監視
瞬間的なスナップショットだけでなく、継続的な監視が重要です。
pt-kill の活用
Percona Toolkit の pt-kill を使うと、条件に合うクエリを自動的に停止できます。
# 60秒以上実行中のSELECTを表示(実際には停止しない)
pt-kill --host=localhost --user=root \
--busy-time 60 --match-command Query \
--match-info "SELECT" --print
# 実際に停止する場合は --kill を追加本番環境では慎重に使う必要がありますが、暴走クエリへの自動対処として有効です。
SHOW PROCESSLIST は MySQL の「今」を見るための基本ツールです。問題発生時に素早く状況を把握できるよう、出力の読み方に慣れておきましょう。