ディスク容量が100%!
サーバーをメンテしていたところ、最近になってディスク使用率があっという間に100%になってしまうとい現象が起きました。
こういうときは、du -m
や find . -mmin -60 -ls
などで容量の大きいファイルを見つけて削除すれば空きます。ncduを使うとより楽に容量の重たいファイルを見つけることができるようです。
見つからない容量の大きいファイル
ところが、一週間くらいかけて少しずつ容量の大きいファイルを探しては削除や空で上書き(echo "" > xxx.log
)してもみるみるうちにディスクは圧迫されすぐに100%になってしまいました・・・。
容量が空いていないと実行できないコマンドもいくつかあるため、少し空けてはメンテを行いということを繰り返す。
ついには tune2fs
でファイルシステム中の予約ブロックを減らすまでに至り、もうこれ以上減らせるものがないと悟りました。
プロセスによって掴み続けられているファイル
プロセスがファイル(ファイルのinode)を掴んでいると、プロセスがファイルを開放するかプロセスが終了するまでそのファイルがどんな姿形になっていようが書き込み続けるという挙動をします。
こういったプロセスは lsof
で特定することができました。
sort - How to find the largest open files? - Unix & Linux Stack Exchange
こちらのリンクに書き込まれている以下のコマンドにより、lsofを使ってプロセスが掴んでいるファイルを容量順にソートしてくれるのですぐに見つけることができました。
lsof \
| grep REG \
| grep -v "stat: No such file or directory" \
| grep -v DEL \
| awk '{if ($NF=="(deleted)") {x=3;y=1} else {x=2;y=0}; {print $(NF-x) " " $(NF-y) } }' \
| sort -n -u \
| numfmt --field=1 --to=iec
その結果がこれです。
39G /var/log/ufw.log
42G /var/log/kern.log
42G /var/log/syslog
エッッッッッッッッッ
しかし、そこにはファイルが存在していません。ファイルが存在していないけど書き込まれ続けているという現象。
そこで思い出しました。ログを整理しようとして echo "" > /var/log/ufw.log
ではなく rm
したあの日の事を。
こちらは rsyslogd
を再起動するだけで簡単に解決しました。
なぜ肥大化したのか
そもそもなぜ肥大化したのか、そしてファイルは見つからなかったのか。
logrorateも正常に動いているのにもかかわらず肥大化した理由は、単にそこにファイルがないからlogrorateしようにもできないということでした。
本来、logrotateの中でrsyslogdを再起動しています。しかし、rsyslogdが管理しているファイルをすべてrm
してしまったことにより、rsyslogdが再起動する機会を人の手によってすべて奪ってしまったのです。
そうやってlogrotateで削除や圧縮、再起動もされることもなく、duやfindでも見つからない巨大ファイルが出来上がります。
対策
log系ファイルは削除ではなく、空で上書きするに徹すればいいというわけではありますが何らかのオペレーションでファイルが開いているプロセスを削除してしまうかもしれません。そうなったら気づけない。
簡単な対策として定期的にrsyslogdなどのプロセスをcronで再起動するようにするだけでもいいのかもしれません。