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枯渇?

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

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