空き容量があるのにNo space left on deviceになる原因と対処|inode枯渇の調査手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxトラブルシューティング > 空き容量があるのにNo space left on deviceになる原因と対処|inode枯渇の調査手順
「ディスクの空き容量はまだあるはずなのに、ファイルが作れない」
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枯渇の三大原因


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

なぜ空き容量があるのに「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. 対象ディレクトリのファイル数を正確に確認する

絞り込んだディレクトリのファイル数をfindwc -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% /

削除後にIUse%が大幅に下がっていれば、セッションファイルが原因だったと確定できます。再発防止には後述のcronによる定期削除を設定してください。

メールキュー(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

RHEL 9 / Rocky Linux 9では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を増やしすぎるとinode領域がディスクを余分に消費します。大容量のファイルを扱うストレージサーバーでは逆効果になるため、ワークロードに合わせて設定してください。XFSファイルシステムではinodeは動的割り当てなのでこの問題が起きにくく、inode枯渇が頻発する運用環境ではファイルシステムの選定自体を見直す選択肢もあります。

本記事のまとめ

やりたいこと コマンド
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
「空き容量があるのにNo space left on deviceになる」という状況は、df -iでinode使用率を確認するという一手で原因の方向性が分かります。100%のパーティションが見つかれば、findコマンドでファイルが集中したディレクトリを特定し、削除して復旧という流れです。

再発防止にはcronによる定期クリーンアップと、監視へのinode使用率チェックの追加が有効です。ブロック容量とinode使用率の両方を把握しておくことで、次回からは「なぜかファイルが書けない」という状況でも慌てずに原因を切り分けられるようになります。

inode枯渇の調査手順を身につけたら、次はサーバー全体のトラブル対応スキルを体系的に固めませんか?

inode枯渇のような「見えない障害」を現場で即座に切り分けられるのは、ファイルシステムの内部構造を体系的に理解しているエンジニアだけです。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

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

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

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

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

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

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

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

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

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

この記事を書いた人

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

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

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