logrotateの設定を間違えてサーバを殺めてしまった話

その時は突然やってきた

何気なくサーバにログインしてみるとゾッとするメッセージが。

 $ less /var/-bash: cannot create temp file for here-document: No space left on device
 -bash: cannot create temp file for here-document: No space left on device

かつて学生をしていた共有ドライブの小さな学校でたびたび見かけた表示でしたが、空き領域がないと言われてもディスクを圧迫するようなサイズのファイルが生成された覚えはなく、実際にdfで確かめてもスペースは十分に空いていました。

嫌な予感しかしないinodeを見てみると……

inodeが枯渇してしまっていました。
そんな大量のファイルを作った覚えないんだけど!と言いながらどこでinodeが使われているのか調べてみると予想だにしない結果が。

ログディレクトリでinode枯渇?

nginxのログディレクトリという予想の斜め上の状況でした。今までこんなことが起きるわけもありません。

ディレクトリを確かめようと思ってもまともに操作できないレベルにまで陥っていました。

なんとか覗いた結果

なんとかディレクトリ内のファイルを見てみた結果がこちらです。

ログローテーションが狂ってやがる……

本来ならばaccess.log, access.log.1, access.log.2.gz, ... とローテーションされるべきところが既にローテーション済みのログも含めて複製されてしまっています。

どうしてこうなったという話なんですが、少し前にlogrotateの設定変えたことが原因でした。
というのも.log以外のフォーマットのログもローテーションしたいという思いで何の考えもなしに

- /var/log/nginx/*.log {
+ /var/log/nginx/*.log* {
    daily
    compress
...
}

と気の狂いすぎた変更をしてしまったわけですね。さすがに気づけよという話なんですが。

この変更で毎日すべてのログのローテーションをしてくれるバイバイン状態になりO(2^n)のオーダーでみるみる増加してしまった結果が141万ファイルの正体でした。

原状回復

急いでログファイルたちを消そうとしましたがrmの引数に渡す方式ではまともに対処できないのでディレクトリごと一掃するという暴挙に出るはめになりました……。

教訓

1417000というファイル数から逆算すると

\log_2 1417000 \approx 20.43

ということでざっくり20日前後でinodeを食い尽くした計算になります。
設定ファイルいじるときは影響を見極めようね!

Leave a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です