- サーバー
- 技術 💻
Linuxでrmしても容量が減らない原因と対処法
Linuxで大きなファイルをrmしてもdfの空き容量が増えない場合、原因のほとんどは「そのファイルを開いたままのプロセスがいる」ことです。rmが消すのはファイルの「名前」だけで、中身(データ)は、開いている全てのプロセスが手放すまでディスク上に残ります。
ディスク逼迫の対応中に起きると焦る現象ですが、仕組みが分かれば数分で解決できます。この記事では、原因の特定から安全な対処、dfとduが合わない他の原因、再発防止までを解説します。
なぜrmしても容量が減らないのか
Linuxでは、ファイルは「名前(ディレクトリのエントリ)」と「実体(inodeとデータ)」に分かれています。
- rmが消すのは名前だけ
- 実体は、名前が0個になり、かつどのプロセスも開いていないときに初めて解放される
ログを書き込み続けているアプリが開いているログファイルをrmすると、名前は消えますが、アプリはまだそのファイルに書き込み続けています。そのため容量は解放されず、名前のないファイルがディスクを占有し続ける状態になります。
手順1:削除済みなのに開かれているファイルを探す
lsof +L1
+L1 は「リンク数(名前の数)が1未満=削除済み」のファイルだけを表示するオプションです。
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
java 1234 app 12w REG 253,0 10737418240 0 45678 /var/log/app/app.log (deleted)
(deleted) と表示されているのが犯人です。PID(プロセス番号) と FD(ファイルディスクリプタ番号、この例では12) を控えます。
lsofが入っていない環境では、/procから直接探せます。
find /proc/*/fd -ls 2>/dev/null | grep '(deleted)'
手順2:容量を解放する
方法は2つあります。サービスへの影響が小さい順に紹介します。
方法A:プロセスを止めずに、中身を空にする(推奨)
開いたままのファイルは、/proc経由でアクセスして中身を切り詰めることができます。
: > /proc/1234/fd/12
または
truncate -s 0 /proc/1234/fd/12
PIDとFD番号は手順1で控えたものに置き換えてください。プロセスを止めずに容量を即座に解放できるので、本番の緊急対応ではこれが第一選択です。
方法B:プロセスを再起動する
アプリを再起動(または再読み込み)すると、プロセスがファイルを手放すので容量が解放されます。サービス停止を伴うため、メンテナンス時間が取れる場合や、方法Aが使えない場合の選択肢です。
多くのサービスは、再起動しなくてもログファイルを開き直すシグナル(例:kill -HUP <PID> や、各サービスの reload コマンド)に対応しています。ドキュメントで確認してみてください。
次から:ログを消すときは「rm」ではなく「空にする」
稼働中のプロセスが書いているログを小さくしたいときは、最初からrmではなく、中身を空にするのが正解です。
: > /var/log/app/app.log
ファイル(名前)は残ったまま中身だけが0になり、書き込んでいるプロセスもそのまま動き続けます。
dfとduが合わない、その他の原因
「dfは使用中が多いと言うのに、duで数えると少ない」場合、削除済みファイル以外にも原因があります。
1. root用の予約領域
ext4などのファイルシステムは、既定で容量の約5%をroot用に予約しています。一般ユーザーから見ると、空きがあるはずなのに書き込めない、という状態になります。
tune2fs -l /dev/sdX | grep -i "reserved block count"
2. マウントの下に隠れたファイル
ディレクトリにファイルが入った状態で、その上に別のディスクをマウントすると、元のファイルは見えなくなるのに容量は使い続けます。 duでは数えられないので、dfとずれます。
アンマウントして確認するか、別の場所に元のディスクをバインドマウントして中を覗くと見つかります。
3. inodeの枯渇(容量があるのに書けない)
「No space left on device」なのに、dfでは空きがある場合は、inode(ファイルの管理情報の数)が枯渇している可能性があります。小さなファイル(キャッシュ・セッション・メールキュー等)が大量にあると起きます。
df -i
IUse% が100%に近ければinode枯渇です。大量の小ファイルがあるディレクトリを探して整理します。
du --inodes -x / 2>/dev/null | sort -n | tail -20
容量を食っているものを探す基本コマンド
df -h # ファイルシステムごとの使用状況
du -xh --max-depth=1 / | sort -h # 直下のディレクトリごとの使用量
du -xh /var/log | sort -h | tail # 特定ディレクトリの大きいもの
-x を付けると、別のファイルシステムをまたがずに集計できるので、どのディスクを何が使っているかが正確に分かります。
再発防止:logrotateの設定を確認する
ログが肥大化する根本対策は、ログローテーションです。logrotateでは、ローテーション時の扱いに2つの方式があります。
- create方式+アプリに開き直させる — 古いファイルを別名にし、新しいファイルを作ったうえで、postrotateでアプリにログを開き直させる(reload等)。最も確実
- copytruncate方式 — ファイルをコピーしたあと、元のファイルを空にする。アプリが開き直しに対応していない場合に使う。コピーから空にするまでの一瞬に書かれたログが失われる可能性がある
/var/log/app/*.log {
daily
rotate 14
compress
missingok
notifempty
copytruncate
}
アプリがログの開き直しに対応していればcreate方式、対応していなければcopytruncate方式を選びます。「ローテーションしているのに容量が減らない」場合は、アプリが古いファイルを掴んだままになっていないかを、lsof +L1で確認してください。
よくある質問
Q. rmしたファイルを復元できますか?
A. プロセスが開いたままなら、/proc経由で中身をコピーできます(cp /proc/<PID>/fd/<FD> /tmp/restore.log)。プロセスが手放した後は、通常の方法では復元できません。
Q. 本番でプロセスを再起動できません。
A. : > /proc/<PID>/fd/<FD> で中身を空にする方法なら、プロセスを止めずに容量を解放できます。
Q. dfとduの数字が少しだけずれるのは異常ですか? A. ファイルシステムの管理情報や予約領域の分だけずれるのは正常です。大きくずれる場合に、本記事の原因を確認してください。
Q. コンテナ環境でも同じですか? A. 仕組みは同じです。コンテナ内のプロセスが削除済みファイルを開いている場合は、ホスト側からもlsof等で確認できます。
まとめ
- rmしても容量が減らない原因の多くは、プロセスが削除済みファイルを開いたまま
- lsof +L1 で特定し、: > /proc/PID/fd/FD で止めずに解放する
- 稼働中のログは、rmではなく : > ファイル名 で空にする
- dfとduが合わない他の原因は、予約領域・隠れたマウント・inode枯渇
- 再発防止は logrotate。アプリの開き直しに対応しているかで方式を選ぶ
株式会社RJCが携わるシステムの多くは、Linuxサーバーの上で長時間動き続けています。仕組みを知っていれば数分で終わる対応を、チームの知識として共有しています。
▶ RJC丸わかり https://www.r-jc.jp/guide/?mediacode=02-00001-003
▶ エントリーはこちら(1〜2分で完了します) https://www.r-jc.jp/recruitment/?mediacode=02-00001-003
株式会社RJC ― SI事業・SES事業・AI駆動開発。未経験からエンジニアに育てるのが得意な会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。