iotopコマンドでディスクI/Oを使うプロセスを特定する方法|iostatとの違いやインタラクティブ操作も

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtips, システム管理コマンド > iotopコマンドでディスクI/Oを使うプロセスを特定する方法|iostatとの違いやインタラクティブ操作も
「ディスクI/Oが急に詰まり始めた時、どのプロセスが犯人か特定できない」
本番運用でiowaitが上がった瞬間に、誰しも一度は経験する困りごとです。

top や vmstat ではシステム全体のI/O負荷は見えても、「どのPIDが書いているか」までは追えません。
そこで使いたいのが iotopコマンド です。

この記事では、iotopコマンドの基本的な使い方から、画面の読み方、--onlyやバッチモードの活用、
高負荷時の犯人プロセス特定の手順まで体系的に解説します。

実行環境:RHEL 9.4 / Ubuntu 24.04 LTSで動作確認済みです。

この記事のポイント

・iotopはプロセス単位でディスクI/O使用量をリアルタイム表示できる
・root権限で実行する必要がある(sudo iotop)
・--onlyオプションでI/Oのあるプロセスだけに絞り込める
・iostatでデバイス、iotopでプロセスを見るのが切り分けの定石


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

iotopとは何か?iostatとの違い

iotopはLinuxのプロセスごとにディスクI/O使用量をリアルタイム表示するコマンドです。
topのI/O版と捉えるとイメージしやすい。カーネルのtaskstats機能を呼び出して各プロセスのI/O統計を取得しています。

よく似た名前のiostatとの最大の違いは「集計の単位」です。iostatはデバイス単位、iotopはプロセス単位の集計を行います。
比較項目 iotop iostat
集計単位 プロセス(TID/PID) ブロックデバイス
主な用途 犯人プロセスの特定 ディスク全体の負荷把握
必要なパッケージ iotop sysstat
必要な権限 root権限が必須 一般ユーザーで実行可能
過去データの参照 不可(リアルタイムのみ) sar -dで過去データ参照可
「ディスク全体が遅い」を調べるならiostat、「誰が遅くしているか」を調べるならiotop。
両者を組み合わせて使うと障害切り分けの精度がぐっと上がります。

iotopコマンドの基本的な使い方

1. インストール

iotopは各ディストリビューションの標準パッケージリポジトリから入手できます。
ただし最小インストール構成では入っていないことが多いため、現場のサーバーには事前にインストールしておきましょう。

# RHEL / Rocky Linux / AlmaLinux $ sudo dnf install iotop # Ubuntu / Debian $ sudo apt install iotop # インストール確認 $ which iotop /usr/sbin/iotop $ iotop --version iotop 0.6

2. 基本実行と画面の読み方

iotopは内部でカーネルのtaskstats機能を呼ぶため、root権限が必要です。
sudoを付けて実行してください。

$ sudo iotop Total DISK READ : 0.00 B/s | Total DISK WRITE : 45.62 K/s Current DISK READ: 0.00 B/s | Current DISK WRITE: 52.13 K/s TID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND 1234 be/4 mysql 0.00 B/s 30.50 K/s 0.00 % 3.21 % mysqld --datadir=/var/lib/mysql 5678 be/4 root 0.00 B/s 12.30 K/s 0.00 % 1.05 % rsyslogd -n 9012 be/4 nginx 0.00 B/s 2.82 K/s 0.00 % 0.42 % nginx: worker process

ヘッダー部分はシステム全体のI/O累計と現在のスループット、その下のプロセス一覧が1秒ごとに更新されます。
各列の意味は次の通りです。
列名 意味
TID スレッドID(-Pオプションを付けるとPID表示に変わる)
PRIO I/O優先度(be=best effort、rt=リアルタイム、idle=アイドル)
USER プロセスの実行ユーザー
DISK READ 読み込み速度(B/s, K/s, M/s)
DISK WRITE 書き込み速度(B/s, K/s, M/s)
SWAPIN スワップインに費やされた時間の割合
IO I/O待ちで止まっていた時間の割合(高いほど詰まっている)
COMMAND 実行コマンドライン
特に注目すべきは IO 列です。値が大きいプロセスがディスクのボトルネックになっています。

3. インタラクティブモードのキー操作

iotop実行中はキー入力で表示を切り替えられます。覚えておくと現場での切り分けが速くなります。
キー 機能
o I/Oが0でないプロセスだけ表示する(--onlyトグル)
p TID表示とPID表示を切り替える
a 速度表示と累積量表示を切り替える
r ソート順を逆転する
q iotopを終了する

よく使うオプションと実務活用

1. --only:実際にI/Oを発生させているプロセスだけ表示する

デフォルトでは待機中のプロセスも全部並ぶため、画面が情報過多になりがちです。
--only を付けると、現在進行形でI/Oを発生させているプロセスだけに絞り込めます。

$ sudo iotop --only Total DISK READ : 0.00 B/s | Total DISK WRITE : 18.45 M/s TID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND 8421 be/4 mysql 0.00 B/s 18.20 M/s 0.00 % 92.15 % mysqld --datadir=/var/lib/mysql 9087 be/4 root 0.00 B/s 0.25 M/s 0.00 % 4.88 % rsync -av /data /backup/

CPU使用率がほぼ0なのに書き込みが続くシステムを観察したい場合に最も使う形です。

2. -b/--batch:ログにリダイレクトする

cronで定期収集したい時や、SSH越しに長時間モニタリングしたい時はバッチモードを使います。
インタラクティブな画面更新を行わず、標準出力にテキストとして書き出します。

# 1秒ごとに10回サンプリングしてログ保存 $ sudo iotop -b -n 10 -d 1 --only -t -o > /var/log/iotop-$(date +%F).log # 出力例(-tでタイムスタンプ付き) 14:32:05 Total DISK READ : 0.00 B/s | Total DISK WRITE : 18.45 M/s 14:32:05 TID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND 14:32:05 8421 be/4 mysql 0.00 B/s 18.20 M/s 0.00 % 92.15 % mysqld

-d で間隔(秒)、-n でサンプリング回数、-t でタイムスタンプ付きの形式に変わります。
深夜帯のスポット監視や、バックアップ実行中のI/O変動を後から振り返る用途に向いています。

3. -p PID:特定プロセスを継続監視する

「mysqldだけ追いたい」「特定のバックアップスクリプトのI/Oを記録したい」場合は -p で対象を絞り込みます。

# mysqldのPIDを取得 $ pgrep -x mysqld 1234 # mysqldのI/Oだけ表示 $ sudo iotop -p 1234 # 子プロセスも合わせて追う場合 $ sudo iotop -p $(pgrep -d',' mysqld)

4. -P/--processes:スレッドではなくプロセス単位で集計する

デフォルト表示はTID(スレッド)単位ですが、-P を付けるとプロセス単位の合計値になります。
マルチスレッドのDBや言語ランタイム(Java、Node.js等)で「プロセス全体のI/O量」を見たい時に使います。

# プロセス単位 + I/Oありのみ $ sudo iotop -P --only Total DISK READ : 0.00 B/s | Total DISK WRITE : 22.10 M/s PID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND 8421 be/4 mysql 0.00 B/s 21.85 M/s 0.00 % 89.24 % mysqld --datadir=/var/lib/mysql

実サーバーでのI/O高負荷切り分け事例

I/O待ちが上がった時、現場で踏むべき手順をDBサーバー(host: db-prd-01、IP: 10.0.x.x、Rocky Linux 9.4)での実例で紹介します。

1. iostatでデバイス側を確認する

$ iostat -x 1 5 Device r/s w/s rkB/s wkB/s await %util nvme0n1 0.00 320.5 0.00 18450.20 85.2 98.4

%util が98%、await が85ms。この時点でストレージが詰まっていることは確定です。
ただし「誰のせいか」はまだ分かりません。

2. iotopで犯人プロセスを特定する

$ sudo iotop --only -P -d 2 Total DISK READ : 0.00 B/s | Total DISK WRITE : 18.45 M/s PID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND 8421 be/4 mysql 0.00 B/s 18.20 M/s 0.00 % 92.15 % mysqld --datadir=/var/lib/mysql 9087 be/4 root 0.00 B/s 0.25 M/s 0.00 % 4.88 % rsync -av /data /backup/

mysqldが18.2 MB/s、IO待ち92.15%でほぼ独占状態。
このサーバーで実際に観測した値で、原因はsysbenchの長時間ベンチマークがcron経由で残っていたケースでした。

3. プロセスの中身まで踏み込む

PIDが分かったら、次は中で何をしているかを掘り下げます。

# プロセスが開いているファイルを見る $ sudo ls -l /proc/8421/fd | head lrwx------ 1 mysql mysql 64 May 4 14:30 0 -> /dev/null lr-x------ 1 mysql mysql 64 May 4 14:30 3 -> /var/lib/mysql/ibdata1 l-wx------ 1 mysql mysql 64 May 4 14:30 7 -> /var/lib/mysql/sbtest/sbtest1.ibd # システムコールをトレースする $ sudo strace -p 8421 -e trace=read,write -f 2>&1 | head -20

ここまでくれば「どのテーブルファイルにどれだけ書き込んでいるか」が見えてきます。
dmidecode でハードウェア情報を取得して、ディスクの種類(SSD/HDD/NVMe)や搭載メモリ量と合わせて評価すると、根本原因の絞り込みが速くなります。

トラブルシュート・エラー対処

「Could not run iotop as a non-root user」が出た場合

iotopはカーネルのtaskstats機能を直接読むため、一般ユーザーでは起動できません。
sudo を付けて実行してください。

$ iotop Could not run iotop as a non-root user. Please use sudo. # sudoで実行 $ sudo iotop

どうしても一般ユーザーで使いたい場合は、setcapで対応する方法もあります。
ただし権限の付与は他プロセスへの影響が大きいため、本番環境では慎重に判断してください。

# 必要な権限を付与(取り扱い注意) $ sudo setcap cap_net_admin,cap_sys_admin+eip /usr/sbin/iotop # 元に戻す $ sudo setcap -r /usr/sbin/iotop

「Netlink error: No such file or directory」が出た場合

カーネルのCONFIG_TASKSTATSが無効化されている可能性があります。
コンテナ内(dockerやLXC)でiotopを実行した場合に発生しやすい現象です。

# カーネル設定を確認 $ grep TASKSTATS /boot/config-$(uname -r) CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_IO_ACCOUNTING=y

CONFIG_TASKSTATS が「y」でなければiotopは動作しません。
コンテナ内でI/O監視を行いたい場合は、ホスト側でiotopを実行するか、cgroupのblkio統計を直接読む方法を選択してください。
mount コマンドの使い方でマウントポイントの構成を把握しておくと、どのファイルシステムがボトルネックになっているか判断しやすくなります。

表示が頻繁に再描画されて読みにくい場合

-d オプションで更新間隔を長くすると視認性が上がります。

# 5秒ごとに更新(デフォルトは1秒) $ sudo iotop -d 5 # 累積量表示に切り替え(実行開始からの合計量を表示) $ sudo iotop -a

-a を付けると速度ではなく「実行開始からの累積I/O量」が表示されるため、長時間バッチの全体量把握に向いています。

本記事のまとめ

iotopは「どのプロセスがディスクを使っているか」を秒単位で把握できる、現場の必須ツールです。
iostatでデバイス全体の負荷を、iotopでプロセス単位の犯人を、と役割分担で使うと障害切り分けが速くなります。
本番運用では、平常時の出力をログに残しておくと、いざ高負荷が出た時の比較対象として活用できます。
やりたいこと コマンド
iotopを起動する sudo iotop
I/Oのあるプロセスだけ表示する sudo iotop --only
プロセス単位で集計する sudo iotop -P --only
特定PIDを継続監視する sudo iotop -p 1234
バッチモードでログに保存する sudo iotop -b -n 10 -d 1 --only -t -o
累積I/O量で表示する sudo iotop -a
更新間隔を5秒に変更する sudo iotop -d 5

ディスクI/O障害の切り分けで、いつも手探りになっていませんか?

iotopやiostatの使い分けは、現場での障害対応スピードを左右する基礎スキルです。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

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

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

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

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

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

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

登録10秒/合わなければ解除3秒 / 詳細はこちら

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

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として15年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。