はじめに
稼働中のシステムで問題が発生した際、いち早く原因を特定しようと焦ってしまうことはないでしょうか。
今回は、良かれと思って行った障害調査のアクションが、結果的にシステム全体を停止させる二次災害を引き起こしてしまったお話です。
事の顛末
1. アプリケーション障害の調査開始
当時、私は保守に配属されて日が浅く、Linuxに関しても、薄い知識しか持ち合わせていませんでした。
そんなある日のことです。Linux環境で動作しているアプリケーションで障害が発生しました。調査を任された私は原因を特定するため、サーバーにSSHログインし、該当プロセスのログを調査することになりました。
2. viewコマンドによるログの展開
調査対象のログファイルを見つけ、内容を確認するために以下のコマンドを実行しました。
$ view application.log
viewは読み取り専用でファイルを開くコマンドです。誤ってファイルを編集してしまうリスクがないため、ログ確認の用途で日常的に使用していました。
3. 想定外のログ肥大化とメモリ消費
しかし、この時開いたログファイルは、ログローテーションの設定不備などで想定を遥かに超えるサイズに肥大化していました。
viewコマンドの実態はVimを読み取り専用モードで起動しているものであり、ファイルの内容を一度メモリ上に展開しようとします。その結果、巨大なログデータが読み込まれたことで、サーバー上の空きメモリが急激に消費されていきました。
4. そしてあいつがやってくる
メモリが枯渇状態に陥ったことで、奴が覚醒します。そう、Linuxカーネルの安全弁であり死神、 OOM Killer(Out of Memory Killer) 1です。
5. 白羽の矢が立ったのは・・・
ここで最悪の事態が発生します。OOM Killerの標的として選ばれたのは、あろうことか アプリケーションプロセス でした。
これによりプロセスがKillされ、アプリケーション全体が完全に停止。単なる部分的な障害から、 システム全体のダウンへと被害を拡大 させてしまいました。
原因と教訓
この失敗の根本的な原因は、「ファイルサイズを確認せずに、全データをメモリに展開するエディタ系コマンドでログを開いたこと」および「サーバ上で直接ログファイルを開いたこと」です。
本番環境やサーバー上でログを調査する際は、以下の基本を徹底する必要があると痛感しました。
-
ログのダウンロード
ログファイルを端末にダウンロードしてから調査する。 -
ファイルサイズの事前確認
ls -lhなどで、対象ファイルのサイズが安全に開ける容量か必ず確認する。 -
ページャやフィルタリングコマンドの利用
巨大なファイルを扱う場合は、メモリ消費が少ないlessコマンドを使用する。
または、tail -fでリアルタイムの出力を追うか、grep2コマンドで必要な文字列だけを抽出して確認する。
# 安全なログ確認の例
$ less application.log
$ tail -n 1000 application.log
$ grep "ERROR" application.log
おわりに
普段何気なく使っているコマンドでも、その内部的な仕様(今回はメモリへの展開)を正しく理解していないと、思わぬ引き金になることがあります。
あるいは、ログをサーバーから端末上にダウンロードしていれば、今回のようなことは発生しなかったでしょう。
また、ログのローテーション設定やサイズ管理が正しくないと、障害調査にも影響することを身をもって学びました。
障害対応時という焦りやすい状況だからこそ、システムへの影響を最小限に抑える安全なオペレーションを選択することが重要です。皆様が私と同じ轍を踏まないことを願うばかりです。
ここまでお読みいただきありがとうございました。