df -h は正常なのに「No space left on device」…inode 枯渇の調査と復旧手順

夜間バッチが失敗したというアラートが上がった。
oracle ユーザーでサーバにログインし、ログファイルを書き出そうとすると:

$ echo "test" > /u01/app/oracle/diag/test.txt
-bash: /u01/app/oracle/diag/test.txt: No space left on device

ディスクフルかと思って df -h を確認すると、どのパーティションも使用率 40% 前後。容量は十分あるはずなのに、なぜファイルを作れないのか…。

原因は inode(アイノード)の枯渇かもしれません。今回は df -h が正常に見えるのにファイルが作れない状況の仕組みと、調査・復旧の手順を実機ログとともに解説します。


1. 症状

ファイルを作成しようとすると「No space left on device」が返ります。

$ echo "test" > /u01/app/oracle/diag/test.txt
-bash: /u01/app/oracle/diag/test.txt: No space left on device

ディスクフルを疑って df -h を確認しますが、容量は正常です。

$ df -h
ファイルシス        サイズ  使用  残り 使用% マウント位置
/dev/mapper/ol-root    91G   36G   55G   40% /
/dev/sda1            1014M  352M  663M   35% /boot

容量に余裕があるにもかかわらず、ファイルを作成できない状態です。


2. 原因の仕組み

Linux でファイルを作成するには ディスク容量inode の2つが必要です。

リソース確認コマンド枯渇時のエラー
ディスク容量df -hNo space left on device
inodedf -ihNo space left on device

どちらが枯渇しても同じエラーメッセージが返るため、df -h だけでは区別できません。

inode とは何か

inode はファイルの実体(データブロック)とは別に存在するメタデータの入れ物です。ファイル名・パーミッション・タイムスタンプ・データブロックの場所などを記録しています。ファイルを1つ作るごとに inode を1つ消費します。

ext4 では ファイルシステム作成時に inode 数が固定されます(デフォルトは 1 inode / 16KB)。小さなファイルが大量に生成されると、ディスク容量が残っていても inode が枯渇し、新しいファイルを作れなくなります。

主要ファイルシステムの inode 特性

FSinode 確保方式デフォルト作成後の変更
ext4作成時に固定1 inode / 16KB不可
XFS動的確保FS 容量の最大 25%(maxpct=25)maxpct 変更可
Btrfs動的確保制限なし(空き容量に依存)
tmpfs動的確保制限なし(メモリ・swap に依存)

XFS は動的確保のため inode 枯渇が起きにくく、大量の小さなファイルを扱う環境では有利です。Oracle Linux 7 以降は OS のデフォルトが XFS ですが、/u01 などの Oracle 用データ領域を別ディスクで切り出して ext4 でフォーマットしている環境では inode 枯渇のリスクがあります。

Oracle DB 環境では trace ファイルや audit ファイルが蓄積するため、inode 枯渇が発生しやすいパスです。


3. 調査手順

Step 1: df -ih で inode の状態を確認する

df -h-i オプションを加えることで inode の使用状況を確認できます。

$ df -ih
ファイルシス        Iノード I使用 I残り I使用% マウント位置
/dev/mapper/ol-root     46M  46M     0   100% /
/dev/sda1              512K   318  512K     1% /boot

IUse% が 100% のパーティションが枯渇箇所です。

Step 2: どのディレクトリにファイルが集中しているか確認する

inode を消費しているディレクトリを特定します。

$ find / -xdev -type f | wc -l

Oracle DB 環境では diag 配下を重点的に確認します。

$ find /u01/app/oracle/diag -type f | wc -l
$ du -sh /u01/app/oracle/diag/rdbms/*/*/trace/

ファイル数が多いディレクトリが原因箇所です。

Step 3: tune2fs で inode の総数を確認する(参考)

tune2fs -l でファイルシステムの inode 設定を確認できます。

$ tune2fs -l /dev/mapper/ol-root | grep -i inode
Inode count:              xxxxxxx
Free inodes:              0
First inode:              11
Inode size:               256

Free inodes: 0 で枯渇が確定します。なお、マウント中はオンディスクのキャッシュ値を表示するため df -ih の値と乖離することがあります。現在の状態は df -ih で確認するのが正確です。


4. 復旧手順

不要なファイルを削除して inode を解放します。Oracle DB 環境では trace ファイルが典型的な原因です。

古い trace ファイルを確認する

$ find /u01/app/oracle/diag/rdbms/*/*/trace/ -type f -mtime +30 | wc -l

30日以上前の trace ファイルを削除する

$ find /u01/app/oracle/diag/rdbms/*/*/trace/ -type f -mtime +30 -delete

削除後、inode が解放されたことを確認します。

$ df -ih

IUse% が下がり、ファイルが作成できるようになれば復旧完了です。

$ touch /u01/app/oracle/diag/test.txt && rm /u01/app/oracle/diag/test.txt

5. Q&A

Q: df -h は正常なのに No space left on device が出るのはなぜですか?

A: ディスク容量と inode は独立したリソースです。df -h はディスク容量を、df -ih は inode 数を表示します。どちらが枯渇しても同じエラーメッセージが返るため、df -h が正常でも inode が枯渇していればファイルを作れません。まず df -ih で IUse% を確認してください。

Q: inode 数は後から増やせますか?

A: ext4 では増やせません。inode 数はファイルシステム作成時(mkfs)に固定されます。増やすには一度ファイルシステムを作り直す必要があります。XFS は inode を動的に確保するため枯渇しにくく、inode 枯渇が頻発する環境では XFS が有利です。

Q: mkfs.ext4 -N で inode 数を指定しても、指定した数より増えることがありますか?

A: はい、増えることがあります。ext4 の inode 数は「inodes_per_group × ブロックグループ数」の倍数に切り上げられるため、-N 200 と指定しても実際には 224 などより大きな値になる場合があります。-N はあくまで最小値の指定です。実際の inode 数は tune2fs -lInode count で確認できます。

Q: Oracle DB 環境で inode が枯渇しやすいのはなぜですか?

A: バックグラウンドプロセスが trace ファイルをこまめに書き出すためです。特に障害発生時やデバッグ時は大量生成されます。/u01/app/oracle/diag/ 配下を定期的に棚卸しする運用が予防になります。df -h と合わせて df -ih も定期確認の習慣にすることをお勧めします。


6. まとめ

「No space left on device」が出たら df -h だけでなく df -ih を確認する。IUse% が 100% なら inode 枯渇が原因です。

対応フロー

No space left on device
        │
        ▼
df -h → 容量は正常?
        │
   YES  ▼
df -ih → IUse% 100% のパーティションがある?
        │
   YES  ▼
find で該当ディレクトリのファイル数を確認
        │
        ▼
不要ファイルを削除(trace・audit ファイルなど)
        │
        ▼
df -ih で IUse% が下がったことを確認 → 復旧完了