この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
SE時代の2003年頃、私はそう思い込んで、topの画面を30分以上眺め続けた。目立って%CPUが高いプロセスは見当たらない。それでもWebサービスのレスポンスは明らかに重かった。2時間ほど試行錯誤した後、隣に座っていた先輩から声をかけられた。「topの%Cpu行に『wa』ってあるだろ。そこ、何%だ?」
%waという文字には気づいていた。でも意味を知らなかった。画面には「52.8 wa」という数字があった。
この記事では、Linuxのパフォーマンス診断で意外と見落とされる「iowait(I/Oウェイト)」について、20年以上サーバーを運用してきた経験から解説します。「CPU使用率を確認すれば原因が分かる」という思い込みが、現場の調査をどれだけ遠回りにするかを実体験とともにお伝えします。
この記事のポイント
・topコマンドの%Cpu行には「wa(iowait)」という重要な指標がある
・iowaitが高い場合はCPUではなくディスクI/Oがボトルネックの可能性が高い
・iostat -xzコマンドでデバイス単位のI/O状態を特定できる
・「サービスが重い・動かない」はiowait確認から始めると切り分けが速くなる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
topコマンドの「CPU使用率」だけを見ていると現場で詰まる理由
Linuxのパフォーマンス調査でまず開くコマンドといえばtopです。リアルタイムでプロセスごとのCPU使用率が見えるため、「重いプロセスを見つけて対処する」という流れが染み付いている方は多いと思います。ところが、topの画面で最初に目に入るプロセス一覧の「%CPU」列だけを見ていると、大切な情報を見落とします。それがプロセス一覧の上部に表示される「%Cpu(s):」行の「wa」の値です。
%Cpu(s)行には、CPUの時間がどのように使われているかの内訳が表示されています。
・us:ユーザープロセスがCPUを使っている時間の割合
・sy:カーネル(システムコール)がCPUを使っている時間の割合
・id:CPUが何もしていないアイドル時間の割合
・wa:CPUがI/O完了を待っている時間の割合(これがiowait)
私がSE時代に見落としたのは、まさにこの「wa」でした。プロセス一覧の%CPU列は低く、目立つプロセスは何もない。でもサービスは重い。この矛盾の正体は、CPUがI/O待ちで止まっていることでした。
「CPU使用率が低いのになぜ重い?」という状況は、iowaitが高い場合の典型的なパターンです。プロセスがCPUをほとんど使わずにディスクアクセスの完了を待ち続けているため、topのプロセス一覧には「重い犯人」が見えないのです。
セミナーで3,100名以上を指導してきた中で、この「%waを見ていない」という状況は今でもよく見かけます。プロセス一覧の%CPU列しか意識していないエンジニアが、重いサーバーを前にして長時間悩んでいるというケースは珍しくありません。
iowaitとは何か — CPUがI/O完了を「待たされている」時間の正体
iowait(I/Oウェイト)とは、CPUがディスクI/Oやネットワーク越しのI/Oの完了を待機している時間の割合を指します。もう少し正確に言うと、「実行可能なプロセスが存在しない状態で、かつ未完了のI/Oリクエストが存在する時間」がiowaitです。CPUが暇なのではなく、I/Oの完了を待って何もできない状態に陥っています。
以下は、iowaitが高くなっているサーバーのtopの出力例です。%Cpu(s)行のwa(iowait)が52.8%と非常に高い状態を示しています。
# top top - 14:23:01 up 45 days, 2:15, 1 user, load average: 4.82, 4.51, 4.30 Tasks: 287 total, 2 running, 285 sleeping, 0 stopped, 0 zombie %Cpu(s): 15.2 us, 2.1 sy, 0.0 ni, 28.4 id, 52.8 wa, 0.0 hi, 1.5 si MiB Mem : 32017.3 total, 1216.0 free, 26893.8 used, 3907.5 buff/cache MiB Swap: 4096.0 total, 3201.4 free, 894.6 used. 3785.6 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1842 mysql 20 0 1284532 820156 8244 D 8.3 2.5 12:04.21 mysqld 2301 apache 20 0 352448 22312 3824 D 3.1 0.1 1:22.44 httpd 2302 apache 20 0 351784 21988 3820 D 2.8 0.1 0:58.32 httpd
「D」はuninterruptible sleep(割り込み不可スリープ)状態を意味し、I/Oの完了を待っているプロセスがこの状態になります。%CPUがそれほど高くないのにload averageが4を超えているのも、このDプロセスが積み重なっているためです。
iowaitの判断基準として、私が現場で使っている目安を示します。
・waが5%以下 → 正常範囲。I/Oが原因の可能性は低い
・waが5~20% → 注意。I/Oがやや詰まっている可能性あり
・waが20%以上 → 異常。ディスクI/Oがボトルネックになっている可能性が高い
・waが50%以上 → 明らかな異常。即座にiostatsで詳細を確認する
「topのどこを見てるんだ」と言われた日 — SE時代の失敗経験
2003年の夏でした。私が常駐していた客先でWebサービスのレスポンスが突然重くなり、私はその調査を担当することになりました。Red Hat Linux 9で動いているApacheとMySQLのシステムです。「topを開いて重いプロセスを探す」——それが私の全てでした。プロセス一覧の%CPU列を30分、ひたすら眺めました。MySQLが少し高めでしたが、killするほどではありません。Apacheも同様です。
次にやったのはメモリの確認です。
freeコマンドでスワップ使用量を確認しましたが、ほとんど使われていません。ネットワーク帯域も問題なさそうでした。30分が経ち、1時間が経ちました。私は焦るばかりで、原因に近づけていませんでした。「もしかしてハードウェアの問題では?」「MySQLのクエリが悪いのでは?」と、あてずっぽうの仮説を試し続けていました。
そのとき、隣にいた3年先輩のSEが近づいてきて、私の画面を一目見てこう言いました。
「topのどこを見てるんだ」
先輩は私の手からキーボードを受け取り、topの画面の上部——プロセス一覧より上のサマリー行を指さしました。「%Cpu(s)行のwaが52%だ。ディスクが詰まってる」
先輩はすぐに
iostat -x 1 5を入力しました。数秒後、出力には「sda %util 98.4」という数字が表示されていました。調べてみると、MySQLのスロークエリが大量に発生しており、バイナリログへの書き込みがディスク全体を占有していたことが原因でした。ディスクへの書き込みが飽和状態になり、すべてのI/Oが詰まっていたのです。
「topの上を見ていれば最初から5分で分かった話だ」と先輩に言われたとき、私は恥ずかしさよりも、「知らないことがこんなにも調査の時間を奪うのか」という衝撃を感じました。topという同じコマンドを使っていながら、先輩と私では見ている情報が根本的に違っていたわけです。
20年以上が経った今も、この体験は私がセミナーで「topを開いたらまず%Cpu行のwaを確認する習慣を身につけてください」と伝える理由になっています。
iowaitを確認・特定するコマンドと手順
iowaitが高いことをtopで確認したら、次のステップは「どのデバイスのI/Oが詰まっているか」を特定することです。そのための定番コマンドがiostatsです。iostatはsysstatパッケージに含まれており、RHEL系ならdnf install sysstat、Ubuntu/Debian系ならapt install sysstatでインストールできます。
1. iostat -xzでデバイス単位の状態を確認する
# iostat -xz 1 3 Linux 5.14.0-70.13.1.el9_0.x86_64 (server-prod01) 09/16/2026 _x86_64_ (4 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 15.20 0.00 3.60 52.80 0.00 28.40 Device r/s w/s rkB/s wkB/s r_await w_await svctm %util sda 0.20 185.40 3.20 74160.00 0.50 285.30 5.30 98.40 dm-0 0.00 92.70 0.00 37080.00 0.00 571.20 5.30 49.20 dm-1 0.00 92.70 0.00 37080.00 0.00 570.90 5.30 49.20
iostat -xz 1 3は「拡張統計(-x)をアクティブなデバイスのみ表示(-z)で、1秒間隔で3回取得する」という意味です。出力の読み方のポイントは次の通りです。
・%util(デバイス使用率):100%に近いほどそのデバイスが飽和している。上の例ではsda(実ディスク)が98.4%で飽和状態
・w_await(書き込みI/Oの平均待ち時間、ミリ秒):通常のSSDで1~5ms、HDDで10~30ms程度が目安。285msは明らかな異常値
・wkB/s(1秒あたりの書き込みデータ量):74,160KB(約72MB)と大量の書き込みが発生している
この出力からは「sdaへの書き込みが1秒あたり185リクエスト・72MB/sで飽和し、I/Oの待ち時間が285msにまで膨らんでいる」という状況が読み取れます。sda(物理ディスク)の飽和がdm-0とdm-1(LVMの論理ボリューム)に影響していることも確認できます。
2. iotopで書き込みの原因プロセスを特定する
どのデバイスが詰まっているかが分かったら、次に「何がそれほどのI/Oを発生させているか」をiotopコマンドで特定します。iotopはtopがCPUを可視化するのと同じように、ディスクI/Oをプロセスごとにリアルタイムで可視化してくれます。iotop -o(アクティブなプロセスのみ表示)を実行すると、I/Oを使っているプロセスが一目で分かります。MySQLのバイナリログが原因ならmysqldがDISK WRITEの上位に表示されるはずです。「サービスが動かない・エラーになる」ときのiowait切り分け手順
「Webアプリケーションがタイムアウトになる」「DBへの接続が異常に遅くてエラーが返ってくる」「コマンドを打っても応答が数十秒返ってこない」——こういったエラーや障害が発生したとき、iowaitを最初に確認する習慣があると調査の時間が大きく変わります。私が現場で実践している切り分けの手順は次の通りです。
1. topでiowaitの有無を確認する(30秒)
topを起動し、%Cpu(s)行の「wa」を確認します。・waが5%以下 → I/Oが原因の可能性は低い。usとsyを見てCPU起因を調べる方向へ
・waが20%以上 → ディスクI/Oがボトルネックと判断し、次のステップへ進む
2. iostat -xzで原因デバイスを特定する(1~2分)
waが高い場合、iostat -xz 1 5を実行して%utilが80%以上のデバイスを探します。複数のデバイスに分散している場合は最も%utilが高いデバイスから調べます。3. iotopで原因プロセスを特定する(1~2分)
デバイスが特定できたらiotop -oでどのプロセスがI/Oを発生させているかを特定します。4. エラーや動かない原因の種類別に対処する
原因プロセスと用途が分かれば、対処方法が決まります。現場でよく見るケースは次の通りです。・MySQLやPostgreSQLのスロークエリ:スロークエリログを有効にして重いクエリを特定し、インデックス追加やクエリ最適化を検討する
・Apacheのアクセスログが大量に書き込まれている:ロギング設定を見直す。必要に応じて
logrotateを調整するか、ログ出力先をRAMディスク(tmpfs)に変更する・バックアップ処理との競合:深夜バッチがディスクを占有している場合は、
ioniceコマンドでバックアッププロセスのI/O優先度を下げる・HDDの物理的な劣化:%utilが高いのにI/O量が少ない場合は、
smartctl -a /dev/sdaでSMART情報を確認する。Reallocated_Sector_Ctの値が増加していればディスク交換のサインです私のセミナーでも「サービスが重くてエラーが出ている」という受講生の相談を受けることがありますが、iowaitを確認していないケースが多いです。topのプロセス一覧だけで数時間悩んでいた問題が、%waを見た瞬間に方向性が決まるということは珍しくありません。
重要なのは「エラーやサービスの不具合が起きたとき、最初にtopの%waを見る」という確認の順番を習慣にすることです。私がSE時代に2時間無駄にしたのは、この確認順序を知らなかったからです。仕組みを一度理解してしまえば、waの確認は5秒で終わります。
dmesgコマンドでディスクのハードウェアエラーが出ていないかも忘れずに確認してください。
dmesg | tail -30を実行し、「I/O error」「EXT4-fs error」「hard resetting link」といったメッセージが出ていれば、ディスクの物理的な問題を疑う必要があります。まとめ
「サービスが重い・エラーになる」という状況でCPUプロセスばかりを調べて迷走した経験は、Linuxを使い始めた多くの人が一度は通る道だと思います。私自身も同じ道を2時間かけて歩きました。先輩の一言で「topの%Cpu行のwaを見ろ」と気づいてからは、パフォーマンス障害への向き合い方が根本的に変わりました。今はセミナーでも「topを開いたらまず%Cpu行のwaを確認する」という手順を最初に伝えています。iowaitを理解した後は、同じ「サービスが重い」という状況でもアプローチが全く変わります。
以下にiowait診断で使う主なコマンドをまとめます。
| 確認したいこと | コマンド例 | 確認するポイント |
|---|---|---|
| iowaitの有無を確認する | top |
%Cpu(s)行のwaの値(20%超で要注意) |
| デバイス単位のI/O状態を確認する | iostat -xz 1 5 |
%util(80%超で飽和)、w_awaitの値 |
| I/Oが多いプロセスを特定する | iotop -o |
DISK READ/WRITEの大きいプロセス |
| ディスクのカーネルエラーを確認する | dmesg | tail -30 |
I/O errorやハードウェアエラーのメッセージ |
| ディスクの物理的な劣化を確認する | smartctl -a /dev/sda |
Reallocated_Sector_Ctの増加 |
次に読む記事:
・iostatコマンドでディスクI/Oを確認する方法|%utilとawaitの読み方と高負荷時の対処も
・iotopコマンドでディスクI/Oを使うプロセスを特定する方法|iostatとの違いやインタラクティブ操作も
iowaitから始めるサーバー診断の「型」を身につけませんか?
「動かない」「遅い」という障害に対して、正しい切り分け順序で即座に対処できるかどうかは、知識よりも「手順の型」があるかどうかで決まります。ネットの切れ端の情報をつなぎ合わせるだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:LinuxのrootパスワードをSE時代に忘れてサーバーに入れなくなった話|シングルユーザーモード復旧の経験と現役講師が語るパスワード管理の鉄則
- この記事の属するカテゴリ:Linux学習ガイドへ戻る

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