「
No space left on deviceというエラーが出るのに、df -hで確認すると使用率は70%台……」この現象の原因はほぼ確実にinode(アイノード)の枯渇です。Linuxのファイルシステムにはブロック(データを格納する物理的な領域)とは別に、ファイルのメタデータを管理する「inode」という資源があります。
df -hはブロックの使用率しか見ていないため、inode側が枯渇してもスルーしてしまいます。この記事では、
no space left on device inode問題の切り分けから、原因ディレクトリの特定、ファイル削除による復旧、再発防止までを実際のコマンド出力例とともに解説します。RHEL 9 / Rocky Linux 9 / Ubuntu 24.04 LTSで動作確認済みです。この記事のポイント
・df -i でinode使用率(IUse%)が100%かどうかが最初の確認ポイント
・inodeはフォーマット時に数が固定されるため、ブロック容量とは独立して枯渇する
・find /var -xdev -printf '%h\n' | sort | uniq -c | sort -rn | head -20 で大量ファイルの場所を特定できる
・PHPセッションファイル・メールキュー・/tmpの蓄積がinode枯渇の三大原因
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜ空き容量があるのに「No space left on device」になるのか
Linuxでファイルを1つ作成するとき、カーネルは2種類のリソースを消費します。・ブロック:ファイルの実データを格納する物理的な領域
・inode:ファイル名を除くメタデータ(パーミッション・所有者・タイムスタンプ・データブロックへのポインタ)を格納する構造体
どちらか片方でも枯渇すると、Linuxカーネルは同じ「No space left on device」エラーを返します。
df -hが表示するのはブロックの使用率だけなので、inodeが枯渇していても「容量は余っているのにエラーが出る」という一見不可解な状況が生まれます。inodeの個数はファイルシステムのフォーマット時(mkfs)に決まり、後から増やすことができません(XFSは動的割り当てなので例外)。ext4ではデフォルトで16KBあたり1つのinodeが割り当てられます。1バイトのファイルでも1つのinodeを消費するため、小さなファイルを大量に作るワークロードでは、ブロックが余っているのにinodeだけ先に尽きることがあります。
Linuxでは複数のパーティションをそれぞれ独立したファイルシステムとしてmount コマンドの使い方でマウントしており、inodeテーブルはパーティションごとに存在します。「
/のinodeが枯渇しているが/homeは余っている」というようにパーティション単位で枯渇するため、まずどのパーティションが枯渇しているかを特定することが重要です。df -i でinode使用状況を確認する
1. df -i コマンドを実行する
まずdf -iを実行して、すべてのパーティションのinode使用状況を一覧表示します。[root@server01 ~]# df -i Filesystem Inodes IUsed IFree IUse% Mounted on devtmpfs 487671 415 487256 1% /dev tmpfs 490237 1 490236 1% /dev/shm /dev/sda1 3276800 3276800 0 100% / /dev/sda2 655360 12478 642882 2% /boot /dev/sda3 1310720 8941 1301779 1% /home
/dev/sda1(/にマウント)のIUse%が100%になっています。これがNo space left on deviceエラーの原因です。IFreeが0になっており、新規ファイルを作れない状態です。現場では「ディスク使用率を監視していたのにまさかのファイル書き込みエラー」という運用トラブルがよく起きます。
df -h(ブロック)だけでなくdf -i(inode)も定期確認の対象に加えておくことが重要です。2. 各列の意味を確認する
df -iの出力の読み方は次の通りです。・Inodes:そのファイルシステムに存在するinode総数(フォーマット時に決定)
・IUsed:現在使用中のinode数(ファイル・ディレクトリ・シンボリックリンクの合計数)
・IFree:残りの空きinode数(これが0になると新規ファイル作成不可)
・IUse%:inode使用率(100%になるとNo space left on deviceが発生)
df -ihとすると数値がKやMなどの単位付きで表示され、大規模なファイルシステムでも読みやすくなります。inode枯渇しているディレクトリを特定する
IUse%が100%のパーティションが特定できたら、次はそのパーティション内でどのディレクトリにファイルが集中しているかを調べます。実際の運用障害では、このディレクトリ特定が最も時間のかかる作業です。1. find コマンドでファイル数の多いディレクトリを探す
下のコマンドは、対象パーティション内のすべてのファイルの親ディレクトリを列挙し、ファイル数が多い順に表示します。-xdevオプションで他のパーティションをまたがないようにしているのがポイントです。# / パーティションが枯渇している場合(完了に数分かかることがある) [root@server01 ~]# find / -xdev -printf '%h ' | sort | uniq -c | sort -rn | head -20 892413 /var/spool/exim4/input 4821 /var/lib/php/sessions 3204 /var/log/nginx 1082 /var/cache/yum/x86_64/7 847 /var/tmp 231 /usr/lib64 ... # /var のみが枯渇している場合はこちら(処理が速い) [root@server01 ~]# find /var -xdev -printf '%h ' | sort | uniq -c | sort -rn | head -20
/var/spool/exim4/inputに約89万件のファイルが蓄積していることが分かります。メールキューの詰まりが原因です。注意:ルートパーティションが大きい場合、
find /は完了まで数分かかることがあります。IUse%が100%のパーティションだけを対象にすることで処理時間を短縮できます。2. 対象ディレクトリのファイル数を正確に確認する
絞り込んだディレクトリのファイル数をfindとwc -lで正確に数えて確認します。# ファイル数を正確にカウント [root@server01 ~]# find /var/spool/exim4/input -type f | wc -l 892413 # 最も古いファイルのタイムスタンプを確認(いつから蓄積が始まったか) [root@server01 ~]# find /var/spool/exim4/input -type f -printf '%T+ %p ' | sort | head -3 2025-08-12+03:14:22 /var/spool/exim4/input/1kXxyz-0001AB-Cd-D 2025-08-12+03:14:23 /var/spool/exim4/input/1kXxyz-0001AB-Cd-H 2025-08-12+03:15:01 /var/spool/exim4/input/1kXyyy-0002BC-Ef-D
3. ls が使えない場合は find で代替する
ファイル数が数十万を超えるとls /var/spool/exim4/input/*のような展開で「Argument list too long」エラーになることがあります。その場合もfindなら問題なく動作します。# ls: cannot access ...: Argument list too long になる場合の代替 [root@server01 ~]# find /var/spool/exim4/input -maxdepth 1 -type f | head -5 /var/spool/exim4/input/1kXxyz-0001AB-Cd-D /var/spool/exim4/input/1kXxyz-0001AB-Cd-H /var/spool/exim4/input/1kXyyy-0002BC-Ef-D
「No space left on device」が出た時の原因別対処法
PHPのセッションファイルが大量に蓄積している
現場でよく見かけるのが、WebサーバーのPHPセッションファイルの蓄積です。/var/lib/php/sessions(RHEL系)や/tmpにセッションファイルが溜まり続け、ガベージコレクションが正常に動いていないか、セッションのライフタイム設定が長すぎる場合に起きます。# セッションファイルの保存先を確認 [root@server01 ~]# php -i | grep session.save_path session.save_path => /var/lib/php/sessions => /var/lib/php/sessions # ファイル数を確認 [root@server01 ~]# find /var/lib/php/sessions -type f | wc -l 4821 # 7日以上前のセッションファイルを削除 [root@server01 ~]# find /var/lib/php/sessions -name "sess_*" -mtime +7 -delete # 削除後にinode残量を確認 [root@server01 ~]# df -i / Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sda1 3276800 84230 3192570 3% /
メールキュー(Postfix / Exim)が詰まっている
MTA(メール転送エージェント)のキューディレクトリ(/var/spool/postfixや/var/spool/exim4)にメールが大量に溜まるケースです。スパムの踏み台にされた場合や、配送先ドメインのMXレコードが消滅している場合に本番環境で発生します。# Postfixのキュー状況を確認 [root@server01 ~]# mailq | tail -3 -- 89243 Kbytes in 2891 Requests. # deferred(配送保留)メールをまとめて削除 [root@server01 ~]# postsuper -d ALL deferred postsuper: Deleted: 2891 messages # active キューも詰まっている場合 [root@server01 ~]# postsuper -d ALL # 削除後にinode残量を確認 [root@server01 ~]# df -i /var Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sdb1 1048576 3214 1045362 1% /var
mailq | grep -v '^[[:space:]]' | head -20でヘッダを確認してから削除してください。スパム踏み台が疑われる場合は合わせてメールリレーの設定も見直す必要があります。/tmp や /var にテンポラリファイルが蓄積している
ビルドツールやバッチ処理が/tmpや/var/tmpに大量の一時ファイルを生成し、クリーンアップされないまま放置されているケースです。実際の運用では夜間バッチの残骸が数万件蓄積しているケースも珍しくありません。# /tmp のファイル数確認 [root@server01 ~]# find /tmp -maxdepth 1 -type f | wc -l 38204 # 3日以上前のファイルを削除 [root@server01 ~]# find /tmp -mtime +3 -delete # /var/tmp も確認 [root@server01 ~]# find /var/tmp -maxdepth 1 -type f | wc -l 12034 [root@server01 ~]# find /var/tmp -mtime +7 -delete
systemd-tmpfilesが/tmpを自動クリーンアップしますが、カスタムアプリが/tmp以外のディレクトリに一時ファイルを書き出している場合は手動管理が必要です。/etc/tmpfiles.d/にカスタム設定を追加することでsystemd-tmpfilesの管理対象に含めることができます。inode枯渇の再発防止策
1. cronで定期クリーンアップを設定する
原因ごとに定期削除をcronに登録して再発を防ぎます。# /etc/cron.d/inode-cleanup として保存する場合 # PHPセッションファイルを毎日深夜2時に7日以上前のものを削除 0 2 * * * root find /var/lib/php/sessions -name "sess_*" -mtime +7 -delete # /tmp の古いファイルを毎週日曜に削除(.ICE-unix は除外) 0 3 * * 0 root find /tmp -mtime +7 -not -path '/tmp/.ICE-unix/*' -delete 2>/dev/null # /var/tmp の古いファイルを毎月1日に削除 0 4 1 * * root find /var/tmp -mtime +30 -delete 2>/dev/null
2. 監視にinode使用率チェックを追加する
現場では既存の監視スクリプトがブロック使用率しか見ていないことが多く、inode枯渇に気づくのが遅れます。80%を超えた時点でアラートを受け取れれば、実際に枯渇する前に手を打てます。#!/bin/bash # inode使用率が80%を超えたパーティションを検知して通知するスクリプト THRESHOLD=80 HOSTNAME=$(hostname) df -i | awk -v th="$THRESHOLD" 'NR>1 { gsub(/%/, "", $5) if ($5+0 >= th) print $5"% used on "$6 }' | while read -r line; do echo "[${HOSTNAME}] inode警告: ${line}" | mail -s "[WARN] ${HOSTNAME} inode使用率超過" admin@example.com done
3. 次回フォーマット時にinode密度を調整する(ext4)
小さなファイルを大量に扱うサーバー(PHPアプリ・メールサーバーなど)では、mkfs.ext4時に-iオプションでinode密度を上げることができます。# デフォルト(16384バイトあたり1 inode) mkfs.ext4 /dev/sdb1 # 4096バイトあたり1 inodeに高密度化(デフォルトの4倍) mkfs.ext4 -i 4096 /dev/sdb1 # inode数を直接指定する場合 mkfs.ext4 -N 10000000 /dev/sdb1
本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| inode使用率を全パーティション確認 | df -i |
| inode残量を人が読みやすい単位で確認 | df -ih |
| ファイル数が多いディレクトリを探す | find /var -xdev -printf '%h\n' | sort | uniq -c | sort -rn | head -20 |
| 特定ディレクトリのファイル数を数える | find /対象dir -type f | wc -l |
| PHPセッションを7日以上前で削除 | find /var/lib/php/sessions -name "sess_*" -mtime +7 -delete |
| Postfixの保留メールをまとめて削除 | postsuper -d ALL deferred |
| /tmp の3日以上前のファイルを削除 | find /tmp -mtime +3 -delete |
df -iでinode使用率を確認するという一手で原因の方向性が分かります。100%のパーティションが見つかれば、findコマンドでファイルが集中したディレクトリを特定し、削除して復旧という流れです。再発防止にはcronによる定期クリーンアップと、監視へのinode使用率チェックの追加が有効です。ブロック容量とinode使用率の両方を把握しておくことで、次回からは「なぜかファイルが書けない」という状況でも慌てずに原因を切り分けられるようになります。
inode枯渇の調査手順を身につけたら、次はサーバー全体のトラブル対応スキルを体系的に固めませんか?
inode枯渇のような「見えない障害」を現場で即座に切り分けられるのは、ファイルシステムの内部構造を体系的に理解しているエンジニアだけです。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 前のページへ:Linuxで誤って削除したファイルを復元する方法|testdisk・extundeleteの使い方と復旧率を上げる初動対応
- この記事の属するカテゴリ:Linuxトラブルシューティングへ戻る

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