MySQLのSHOW PROCESSLISTでアクティブセッションを確認する方法|長時間クエリの特定とKILL文での強制終了手順

運営:リナックスマスター.JP(代表 宮崎智広)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > Linuxtips > データーベース管理 > MySQLのSHOW PROCESSLISTでアクティブセッションを確認する方法|長時間クエリの特定とKILL文での強制終了手順
「MySQLのサーバーが急に重くなった」「どのクエリが詰まっているのか分からない」と困ったことはないでしょうか。
本番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の調整で改善できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜアクティブセッションの把握が重要なのか

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;

MySQLの実務運用では、こうしたリアルタイム確認を日常の運用手順に組み込んでおくと障害対応が格段に速くなります。Linuxサーバー上でのDB運用を体系的に学びたい方は、Linuxサーバー構築セミナーも参考にしてください。

長時間クエリを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 接続ID:そのセッション自体を切断する。アプリケーション側は接続エラーを受け取る
・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サーバー構築の「型」を体系的に身につけたい方へ、MySQLをはじめとするLinuxサーバー運用を実機ハンズオンで学べるセミナーを開催しています。20年以上・3,100名以上の指導実績をもとに、コマンドを打つだけでなく「なぜそうするか」を体系的に解説します。
>> Linux Master Pro Seminar の詳細はこちら

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録

運営

リナックスマスター.JP(代表 宮崎智広)

株式会社イーネットマーキュリーが運営するLinux教育サイトです。代表の宮崎智広は現役のLinuxサーバー管理者として20年以上の実務経験を持ち、累計3,100名以上のエンジニアを指導してきました。実践型のLinuxセミナーや無料マニュアルの配布を通じてLinux人材の育成に取り組んでいます。