容量とinodeの追跡
目標
dfとduが異なる答えを返す状況を自分で作り、inodeの消費・スパースファイル・ハードリンクが、容量の計算に与える影響を確認します。
なぜ重要なのか
dfはファイルシステムに問い合わせ、duはディレクトリを歩き回って数えます。そのため、名前がなくなったファイル(rmしたがプロセスが開いているもの)は、dfには捕捉され、duには捕捉されません。2つの値がずれること自体が、強力な手がかりです。そして、そのファイルを復旧するには、プロセスを再起動する前に/proc/PID/fdからコピーする必要があります。再起動した瞬間に、機会が消えます。容量が急ぎでも、最初の行動はコピーです。
ステップ
/root/usageディレクトリを作成し、df -hの出力を/root/usage/df-block.txtに、df -iの出力を/root/usage/df-inode.txtに保存してください。/rootの下で、深さ1までのディレクトリのサイズを大きい順に並べて、/root/usage/du-top.txtに保存してください。/root/usage/manyの下に空のファイルを3000個作成し、そのディレクトリのファイル数を数字1行で/root/usage/filecount.txtに書いてください。/root/usage/sparse.imgを100MiBのスパースファイルとして作成し、論理サイズと実際の占有を1行ずつ(バイト単位で、論理が先)/root/usage/sparse.txtに書いてください。2つの値が異なる必要があります。- 削除されたのに開かれているファイルを作成してください。
/root/usage/ghost.logに5MiB以上を書き、そのファイルを開いたままにするプロセスをバックグラウンドで起動したあと、ファイル名を消してください。そして、そのプロセスの/proc/<PID>/fdの一覧から、(deleted)が見える行を/root/usage/deleted.txtに保存してください。 /root/usage/orig.datに1MiBを書き、ハードリンク/root/usage/link.datを作成してください。2つのファイルのinode番号とリンク数を、/root/usage/hardlink.txtに<inode> <링크수>の形式(プレースホルダーはinode番号とリンク数です)で、それぞれ1行ずつ書いてください。2行のinodeが同じである必要があります。/root/usageの下で、サイズが1MiB以上のファイルを、サイズの降順に<바이트> <경로>の形式(プレースホルダーはバイト数とパスです)で/root/usage/big.txtに保存してください。/root/usage/report.txtを次の4行で作成してください。FILES=<3번 값>/SPARSE_DIFF=yes/GHOST_PID=<5번에서 파일을 열고 있는 프로세스의 PID>/SAME_INODE=yes(プレースホルダーは順に、ステップ3の値、ステップ5でファイルを開いているプロセスのPIDです)
参考
- 削除された開いているファイルの作り方:
tail -f /root/usage/ghost.log >/dev/null 2>&1 & echo $!でPIDを得たあと、rm /root/usage/ghost.logです。 - スパースファイル:
truncate -s 100M、実際の占有はdu -B1、論理サイズはstat -c %sです。 stat -c '%i %h' <파일>で、inode番号とリンク数を一緒に見られます(プレースホルダーはファイル名です)。- よくある間違い1: ステップ5でファイルを消したあとプロセスまで殺してしまうと、
(deleted)を観察できません。 - よくある間違い2: ステップ3で
ls | wc -lは、ファイルが多いと遅いです。find ... -type f | wc -lのほうが優れています。
ブロックとinodeの使用量
/root/usageディレクトリを作成し、df -hの出力を/root/usage/df-block.txtに、df -iの出力を/root/usage/df-inode.txtに保存してください。
dfには、人間が読みやすい単位のオプションと、inodeを見るオプションが、別々にあります。
大きなディレクトリを探す
/rootの下で、深さ1までのディレクトリのサイズを大きい順に並べて、/root/usage/du-top.txtに保存してください。
深さを制限すると、上から絞り込んでいけます。別のファイルシステムに移らないオプションも一緒に使ってください。
小さなファイルの大量作成
/root/usage/manyの下に空のファイルを3000個作成し、そのディレクトリのファイル数を数字1行で/root/usage/filecount.txtに書いてください。
ファイル数を数えることと、inodeの使用量を見ることは別です。作成の前後を比べてください。
スパースファイルの2種類のサイズ
/root/usage/sparse.imgを100MiBのスパースファイルとして作成し、論理サイズと実際の占有を1行ずつ(バイト単位で、論理が先)/root/usage/sparse.txtに書いてください。2つの値が異なる必要があります。
duは既定で実際の占有を数えます。論理サイズを見るには、別のオプションが必要です。
削除された開いているファイルの再現
削除されたのに開かれているファイルを作成してください。/root/usage/ghost.logに5MiB以上を書き、そのファイルを開いたままにするプロセスをバックグラウンドで起動したあと、ファイル名を消してください。そして、そのプロセスの/proc/<PID>/fdの一覧から、(deleted)が見える行を/root/usage/deleted.txtに保存してください。
ファイルを開いたままのプロセスをバックグラウンドで維持してから、名前だけを消してください。/procの下のfdのシンボリックリンクに、表示が残ります。
ハードリンクとdu
/root/usage/orig.datに1MiBを書き、ハードリンク/root/usage/link.datを作成してください。2つのファイルのinode番号とリンク数を、/root/usage/hardlink.txtに<inode> <링크수>の形式(プレースホルダーはinode番号とリンク数です)で、それぞれ1行ずつ書いてください。2行のinodeが同じである必要があります。
同じinodeを指す名前が複数あるとき、duが何回数えるかを確認してください。リンク数はstatで見ます。
大きなファイルの一覧
/root/usageの下で、サイズが1MiB以上のファイルを、サイズの降順に<바이트> <경로>の形式(プレースホルダーはバイト数とパスです)で/root/usage/big.txtに保存してください。
findの-sizeは、単位の接尾辞を受け取ります。サイズとパスを一緒に出力するには、-printfを使ってください。
容量調査レポート
/root/usage/report.txtを次の4行で作成してください。
FILES=<3번 값> / SPARSE_DIFF=yes / GHOST_PID=<5번에서 파일을 열고 있는 프로세스의 PID> / SAME_INODE=yes(プレースホルダーは順に、ステップ3の値、ステップ5でファイルを開いているプロセスのPIDです)
前のステップの結果を、キー=値としてまとめます。削除された開いているファイルのサイズは、/procのパスでstatすれば出ます。