本番DBで大量の接続が積み上がっている状況や、1本の長時間クエリが他の処理をブロックしているケースは、Linuxサーバー運用の現場ではよくある出来事です。
この記事では、RHEL 9系/Ubuntu 22.04 LTS以降を想定環境として、MySQLの
SHOW PROCESSLIST コマンドを使ったアクティブセッションの確認方法を解説します。FULL版との使い分け、各カラムの読み方、KILL 文による長時間クエリの強制終了、Sleepコネクション過多の対処まで、実務で役立つ手順をまとめます。この記事のポイント
・SHOW FULL PROCESSLISTでInfo列のクエリ全文を切り詰めなく確認できる
・Time列が大きい行を見てKILL 接続IDで長時間クエリを強制終了できる
・INFORMATION_SCHEMA.PROCESSLISTでWHERE句による絞り込みが可能
・Sleepコネクション過多はwait_timeoutの調整で改善できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜアクティブセッションの把握が重要なのか
MySQLのパフォーマンス障害は、多くの場合「1本のクエリが長時間走り続けている」「大量のSleepコネクションが残っている」「ロック待ちが連鎖している」の3パターンのいずれかです。どのパターンであれ、まず現在の状態をリアルタイムで把握しなければ手が打てません。SHOW PROCESSLIST は「今MySQLで何が起きているか」をその場で確認するコマンドです。スロークエリログが「過去のクエリを事後に分析する」ツールであるのに対し、PROCESSLIST は「今この瞬間の状態を見る」リアルタイムツールです。本番DBが重くなったら最初にこのコマンドを打つ習慣をつけると、原因の切り分けが大幅に早くなります。SHOW PROCESSLISTの基本的な使い方
1. コマンドの実行方法
MySQLにrootまたはPROCESS 権限(他ユーザーのセッションを見るために必要)を持つユーザーで接続し、以下のSQLを実行します。# mysql コマンドで接続する mysql -u root -p # 接続後にPROCESSLISTを表示する SHOW PROCESSLIST;
PROCESS 権限がない一般ユーザーで実行すると、自分のセッションしか表示されません。他のユーザーのセッションも確認するには PROCESS 権限が必要です。権限は SHOW GRANTS FOR 'ユーザー名'@'host'; で確認できます。2. SHOW PROCESSLISTとSHOW FULL PROCESSLISTの違い
通常のSHOW PROCESSLIST では、Info列(実行中のSQL文)が 100文字で切り詰められます。長いクエリの場合、どのSQLが実行中なのかを正確に把握できません。長いクエリの全文を確認するには
SHOW FULL PROCESSLIST を使います。SHOW FULL PROCESSLIST;
+----+------+--------------------+-------+---------+------+--------------+---------------------------------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+--------------------+-------+---------+------+--------------+---------------------------------------------------------------------+ | 3 | app | 192.168.1.10:52100 | appdb | Query | 87 | Sending data | SELECT * FROM orders WHERE status = 'pending' AND created_at < ... | | 5 | root | localhost | NULL | Query | 0 | init | SHOW FULL PROCESSLIST | | 8 | app | 192.168.1.11:49800 | appdb | Sleep | 320 | | NULL | +----+------+--------------------+-------+---------+------+--------------+---------------------------------------------------------------------+
3. 各カラムの読み方
| カラム名 | 意味 |
|---|---|
Id |
接続ID。KILL文に使う番号 |
User |
接続中のMySQLユーザー名 |
Host |
接続元ホスト名またはIPアドレス:ポート番号 |
db |
使用中のデータベース名(USE後) |
Command |
セッション状態(Query / Sleep / Connect 等) |
Time |
現在のCommandが継続している秒数 |
State |
より詳細な処理状態(Sending data / Waiting for lock 等) |
Info |
実行中のSQL文(FULL版でないと100文字で切り詰め) |
注目すべきは Time列とState列の組み合わせ です。Time値が大きく、Stateが「Sending data」「Waiting for lock」「Locked」になっているセッションが問題の原因である可能性があります。
INFORMATION_SCHEMA.PROCESSLISTで絞り込む
セッション数が多い運用環境では、SHOW FULL PROCESSLIST の出力が大量になり、問題のある行を見つけにくいことがあります。INFORMATION_SCHEMA.PROCESSLIST を使えば、SQLのWHERE句で絞り込めます。実行時間が10秒以上のクエリだけを表示する(Sleepは除外):
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, SUBSTRING(INFO, 1, 120) AS INFO_SHORT FROM INFORMATION_SCHEMA.PROCESSLIST WHERE TIME > 10 AND COMMAND != 'Sleep' ORDER BY TIME DESC;
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%lock%' ORDER BY TIME DESC;
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE DB = 'appdb' ORDER BY TIME DESC;
長時間クエリをKILL文で強制終了する
1. 長時間クエリの特定
INFORMATION_SCHEMA.PROCESSLIST でTime値の大きい行を探します。バッチ処理でないオンラインクエリが60秒以上継続している場合は調査対象になります。# 60秒以上実行中のクエリを表示(Sleep除く) SELECT ID, USER, TIME, STATE, SUBSTRING(INFO, 1, 100) AS SQL_SHORT FROM INFORMATION_SCHEMA.PROCESSLIST WHERE TIME >= 60 AND COMMAND != 'Sleep' ORDER BY TIME DESC;
2. KILL文で終了させる
対象の接続IDを確認したら、KILL 文を実行します。-- 接続IDが 123 のセッションを切断する(実行中クエリごと強制終了) KILL 123; -- クエリだけを停止して接続は維持する(MySQL 5.7以降) KILL QUERY 123;
・KILL QUERY 接続ID:実行中のクエリだけを停止し、セッションは維持する
アプリケーションが接続プールを使っている場合、
KILL QUERY の方がセッションを切断しないため影響範囲を最小化できます。ただし、実行中のトランザクションはロールバックされます。3. KILLができない場合の注意点
MySQLのシステムスレッド(User 列が system user になっているセッション)はKILLできません。また、ストレージエンジンがロックを保持中の場合、KILLを実行してもクエリがすぐに終了しないことがあります。KILLを実行した後も同じIDが残り続けるようであれば、SHOW FULL PROCESSLIST で状態を継続して確認してください。よくあるトラブルと対処
Sleepコネクションが大量にある場合
SHOW FULL PROCESSLIST の出力に Command = Sleep の行が大量にある場合、アプリケーションが接続を解放していない可能性があります。まず現在のタイムアウト設定値を確認します。SHOW VARIABLES LIKE 'wait_timeout'; SHOW VARIABLES LIKE 'interactive_timeout';
+---------------------+-------+ | Variable_name | Value | +---------------------+-------+ | wait_timeout | 28800 | | interactive_timeout | 28800 | +---------------------+-------+
wait_timeout = 28800(8時間)はMySQLの初期値です。アイドル状態のコネクションを最大8時間保持し続けることになるため、コネクション過多の原因になります。即時変更する場合(再起動後は元に戻る点に注意):
SET GLOBAL wait_timeout = 300; SET GLOBAL interactive_timeout = 300;
/etc/my.cnf(CentOS/RHELの場合)または /etc/mysql/my.cnf(Ubuntuの場合)に記載します。[mysqld] wait_timeout = 300 interactive_timeout = 300
systemctl restart mysqld または systemctl restart mysql で反映します。Webアプリケーション向けでは300秒(5分)程度が目安ですが、アプリケーションの接続頻度に合わせて調整してください。ロック待ちを見つけた場合
State列に「Waiting for lock」「Waiting for table lock」などが表示されている場合はロック競合が起きています。SHOW ENGINE INNODB STATUS でロックの詳細を確認できますが、MySQL 8.0以降では information_schema.innodb_lock_waits がより直感的です。# MySQL 8.0以降:ロックの保有者と待機中セッションを確認する SELECT r.trx_id AS waiting_trx_id, r.trx_mysql_thread_id AS waiting_thread, b.trx_id AS blocking_trx_id, b.trx_mysql_thread_id AS blocking_thread FROM information_schema.innodb_lock_waits w INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id;
blocking_thread に表示されるIDをKILLすることで、待機中の処理を解放できます。要注意なのは、ロック保有側のトランザクションがロールバックされる点です。アプリケーション側にリトライ処理があるか確認してから実行してください。本記事のまとめ
| やりたいこと | コマンド・SQL |
|---|---|
| アクティブセッションを全件確認 | SHOW FULL PROCESSLIST; |
| 実行時間10秒超のクエリだけ抽出 | SELECT ID, TIME, INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE TIME > 10 AND COMMAND != 'Sleep' ORDER BY TIME DESC; |
| ロック待ちセッションを抽出 | SELECT ID, TIME, STATE, INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%lock%'; |
| 特定セッションを強制切断 | KILL 接続ID; |
| クエリだけ停止し接続は維持 | KILL QUERY 接続ID; |
| Sleepコネクションのタイムアウト変更 | SET GLOBAL wait_timeout = 300; |
| タイムアウト値の現在設定を確認 | SHOW VARIABLES LIKE 'wait_timeout'; |
SHOW FULL PROCESSLIST でセッションの全体像を把握し、Time列とState列を手がかりに問題の原因を絞り込むのが基本的な流れです。スロークエリログと組み合わせることで「今起きている問題」と「過去の傾向」を両面から診断できます。
>> Linux Master Pro Seminar の詳細はこちら
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:mysqlcheckコマンドでMySQLのテーブルをチェック・修復・最適化する方法|定期メンテナンスの実践手順
- この記事の属するカテゴリ:データーベース管理へ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます