1. ホーム
  2. スクリプト・コラム
  3. リナックスシェル

rm -rfの後にディスク領域が解放されない問題の解決方法

2022-01-05 04:52:47

rm -rf で解決するのか?

現在稼働しているプラットフォームはマイクロサービス・アーキテクチャを採用しており、より多くのサービスをデプロイしています。開発環境では、1台のサーバに数十のサービスをデプロイするのが普通です。私の対処法は、まず  /tmp/  ディレクトリを作成して空き容量を確保し、次に一般的なユーザーディレクトリをいくつか確認したところ、いくつかのログファイルが大きなGをいくつも使っていることがわかりました。ここは開発環境なので、それらを削除しただけなので  rm その後は、何も問題ないだろうと甘く見ていたのですが......。

ところが数日後、同僚がマシンのディスクがまたいっぱいになっていることに気づき、「どうしてこんなに早くまたいっぱいになるんだろう」と不思議に思いました。それは、前回の  rm Linuxでは、ファイルの削除をリンクの数で制御しており、ファイル内にリンクがない場合のみ削除される。一般に、各ファイルは2つのリンクカウンタ:i_countとi_nlinkを持っています。 Linuxシステムでi_nlinkとi_countがともに0のときのみ、ファイルは本当に削除されます。 

  • i_countは、現在のファイルユーザー数(または起動数)を示します。
  •  i_nlinkはメディア接続数(ハードリンク数)を示す。

i_countはメモリの参照カウンタで、i_nlinkはディスクの参照カウンタであることが理解できる。 あるファイルが特定のプロセスから参照されると、対応するi_countの数値が増加し、あるファイルへのハードリンクが作成されると、対応するi_nlinkの数値が増加する。LinuxやUnixシステムでは、rmやファイルマネージャーでファイルを削除すると、ファイルシステムのディレクトリ構造からそのファイルのリンクが解除され、ディスク参照カウンターのi_nlinkが効果的に減少するが、i_countは減少しない。 あるプロセスからファイルが呼び出されていて、ユーザーが rm コマンドで "delete" した場合、ls などのファイル管理コマンドでそのファイルを見つけることはできませんが、実際にディスクからファイルが削除されたことにはならないのです。 なぜなら、まだ正常に実行されているプロセスがあり、ファイルの読み書きを行っているため、実際には"delet"されていないことになり、ディスク領域がずっと占有されたままになってしまうからです。サービスプロセスが停止(ファイルハンドルの参照カウントが0になる)または再起動すると、占有していた記憶領域が解放されるだけである。特定のプロセスやファイル名が不明な場合。 lsof | grep deleted プロセスやファイルの名前がわからない場合、これは、削除されたがファイルハンドルが解放されていないすべてのファイルとプロセスを見つけ、プロセスを殺すか、再起動します。

実際には、ファイルの内容を変更するだけで、(例えば echo "test">test.log ) を使用すると、プロセスを再起動せずに空き容量を確保できます。

duとlsの違い

与えられたログファイルに対して、直接 echo "test" > yyzx_tradingcenterservice.log.2020-06-03.log を実行し、さらにdfを実行して、ディスク領域が本当に解放されたことをそれぞれ確認します。

[dev@tjptdebug-no yyzx_tradingcenterservice_logs]$ du -h yyzx_tradingcenterservice.log.2020-06-03.log 
4.0K yyzx_tradingcenterservice.log.2020-06-03.log
[dev@tjptdebug-no yyzx_tradingcenterservice_logs]$ ll -h yyzx_tradingcenterservice.log.2020-06-03.log
-rw-rw-r-- 1 dev dev 7 Jul 8 19:49 yyzx_tradingcenterservice.log.2020-06-03.log

lsの結果は見かけのサイズで、これはファイルシステムのデータ構造でファイルの長さを定義するフィールドと同様だと理解しています。duの結果はディスク使用量で、これは実際に占有されている記憶領域のサイズです。デフォルトの単位はブロックです。ブロックはディスクストレージの基本単位で、ディスクアドレスなどを容易にするものです。この場合のブロックは論理的な単位と理解でき、ファイルにはデータだけでなくファイルを記述する他の情報も含まれるため、1バイトを含むファイルは実際にはディスク上の1バイト以上の記憶領域を占有していることになります。

概要

du == disk usage (ディスク使用量、ディスク占有量)
ls == 見かけのサイズ (ファイル長、ファイルデータ構造で定義されたファイル長フィールド)
ファイルが占有するディスク容量とファイルのサイズは別物です。占有量はファイルシステムのブロックサイズに依存し、一般にデフォルトでは4k(4096)なので、1バイトのサイズのファイルは少なくとも4kを占有するはずですし、ブロックサイズ16kのファイルシステムを作れば、1バイトのファイルでも16kを占有することになるのです。例えば、ファイルシステムのブロックサイズが4Kの場合、13Kのファイルが占有するスペースは13K/4K=3.25ブロックとなり、1ブロックは1ファイルしか占有できないので、実際の占有スペースは4ブロック、つまり16Kとなる。

以上、rm -rfしてもディスク容量が解放されない問題の解決方法についてでした。rm -rfのディスク解放については、スクリプトハウスの過去記事を検索するか、引き続き以下の関連記事を閲覧してください。