[Troubleshooting] 「No space left on device」が出るのに df -h は正常な場合

サーバー運用中に No space left on device エラーが発生し、df -h でディスク容量を確認しても十分な空きがある場合がある。

この現象は、物理的なディスク容量不足ではなく、メタデータ(Inode)の枯渇、または 削除されたがプロセスに保持されたままのファイル(いわゆるゾンビファイル) が原因である可能性が非常に高い。 (※ 本記事は ext4 ファイルシステム を前提としている。)

症状 #

エラーログ

cp: cannot create regular file 'backup.tar': No space left on device
Error: ENOSPC: no space left on device, write

ディスク確認(df -h

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       100G   40G   60G  40% /
  • 状況: ディスクには 60GB もの空きがあるにもかかわらず、システムは「空き容量がない」と判断して処理を拒否している。

原因1:Inode 枯渇(最も多い原因) #

ファイルシステムには、容量(サイズ)だけでなく、**ファイル数(Inode)**にも上限がある。 容量が残っていても、Inode が使い切られると新しいファイルは作成できない。

確認方法

df -i
# Filesystem       Inodes   IUsed    IFree IUse% Mounted on
# /dev/sda1       6553600 6553600        0  100% /
  • IUse%100% の場合、原因は Inode 枯渇である。

犯人特定(ファイルが爆発的に増えた場所を探す)

# ルート配下のディレクトリごとにファイル数を集計(時間がかかる)
find / -xdev -type f 2>/dev/null | cut -d "/" -f 2 | sort | uniq -c | sort -nr

# 現在のディレクトリ配下のファイル数を確認
for i in *; do echo -n "$i: "; find "$i" 2>/dev/null | wc -l; done

よく問題になるパス

  • /var/spool/postfix
  • /var/lib/php/sessions
  • /var/log
  • /usr/src/linux-headers

なぜこれらのディレクトリが原因になるのか これは容量の問題ではなく、「Inode の枠(スロット)」の問題である。

  • Inode エラーによる「No space」は、ディスクの**重さ(容量)**ではなく、**駐車スペース(Inode 数)**が埋まったことを意味する。
  • 1ファイル = 1 Inode: たとえ 0 バイトのファイルでも、必ず Inode を 1 つ消費する。

結論 df -i の Total に対して、特定のディレクトリが 80~90% 以上の Inode を占有している場合、ファイルサイズに関係なく、そのディレクトリがシステム停止の直接原因である。

削除前の注意点 ファイルが多いからといって、すべてが「削除してよいゴミ」とは限らない。必ずファイルの正体を確認すること。

  • 削除してよいもの(Garbage / Cache):
    • sess_*(PHP セッション)
    • postfix/defer(メールスプール)
    • 一時キャッシュファイル
    • mtime が古いファイル
  • 削除してはいけないもの(System / Data):
    • /var/lib/docker/overlay2: 手動削除は絶対禁止。 コンテナ環境が破壊される(docker prune を使用)。
    • サービスデータ: サムネイル画像、稼働中のログ、DB ファイルなど。

Tip: いきなり rm を実行せず、まず ls -lh | head で内容と日時を確認する。

原因2:削除されたが開かれたままのファイル #

ログファイルを rm で削除しても、実行中のプロセスがそのファイルを掴んだままの場合がある。 この場合、df -h には反映されないが、実際のディスク容量は消費されたままになる。

確認方法

lsof | grep deleted
# COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
# java      1234  root   1w   REG  8,1    50G      101  /var/log/app.log (deleted)
  • 意味: java プロセスが削除済みのログファイルを保持したまま、50GB のディスク容量を占有している状態。

解決方法

  • 最も確実な方法:プロセスの再起動Bashsystemctl restart <service_name>
  • 再起動できない場合(暫定対応)Bashcp /dev/null /proc/1234/fd/1

原因3:Docker / OverlayFS の問題 #

コンテナ環境では頻発する。 Docker の overlay2 ファイルシステムやコンテナログが整理されていないと、ホスト側の df -h は正常でも、コンテナ内部で ENOSPC が発生する。

確認・整理

# 停止中コンテナ、未使用イメージ/ネットワークを削除
docker system prune -a

# コンテナログの使用量確認
du -h --max-depth=1 /var/lib/docker/containers

要点まとめ #

  1. No space left on device が出ても、df -h が正常なら容量を疑うな。
  2. Step 1: df -iInode 枯渇を確認。
  3. Step 2: Inode が正常なら lsof | grep deletedゾンビファイルを確認。
  4. Step 3: Docker / K8s 環境では overlay2 とコンテナログの整理を検討。
  5. この順序を守れば、不要なディスク増設や無意味なアプリケーションデバッグを避けることができる。

🛠 마지막 수정일: 2025.12.23

💡 お困りですか?
Zabbix、Kubernetes、各種オープンソースインフラの構築・運用・最適化・障害解析が必要であれば、いつでもご連絡ください。

📧 メール: jikimy75@gmail.com
💼 サービス: 導入支援 | 性能チューニング | 障害解析コンサルティング

What are your feelings

Updated on 2025-12-23