データベースサーバ容量枯渇の障害原因と対応

2020-12-01

未来の自分が忘れそうなので、障害発生の原因と対応を記載しておきます。

なぜこの↓障害が起きたのか

経緯

  • もともとデータベースサーバの空き容量は60GBくらいだった。(※データベースサーバにはMariaDBしか入っていません)
  • 容量増加が250MB/日なのでこのままだと半年くらいで枯渇しちゃう…ということで、非正規型で抱えていたイベントポイント増加量(各順位・各プロデューサーの10分/30分/60分/24時間速)のデータを正規化して保持するよう変更し、容量を確保する作業が裏で進行していた。この作業では中間作業データを一時的に作成する必要があり、30GBくらい必要となった。これで残り容量も30GBになった。⇛作業①
  • これとは別に、各観測サーバで受信した当日のHTML等を一時的にデータベースサーバに格納するバッチジョブがあり、これが20GB/日を一時的に消費する。ただし、すべてのバッチジョブの終了時に20GBのデータは解放され、削除される。⇛作業②
  • 障害発生の前日(11/17)に作業②のバッチジョブが、データベースサーバへのデータ書き込みに後続する処理で失敗した。このバッチジョブは失敗しても翌日に2日分を処理すれば影響がないため、特に通知をしない実装になっていた。20GBのデータは削除されずそのまま放置され、これで残り容量が10GBになった。
  • 障害当日(11/18)に作業②が走り、すべての容量を使い果たし、データベースサーバの容量が枯渇してMariaDBが停止。全機能が停止した。

原因

  1. 容量が限られていることがわかっていたのに作業①の中間作業データを本番データと同じストレージに配置した。
    Block storage(有償の追加ストレージ)を別途借りて中間作業データを配置することも検討したが、わずかな追加費用をケチったのと、マウント作業を面倒くさがった。(この結果、もっと面倒なことになった…)
  2. 作業②で失敗した場合にデータが放置される。また、通知されないので失敗に気づかない。

対応/再発防止

  1. 巨大な中間作業データは本番のストレージ上に作らない。Block storage を一時的に追加で借りてマウントし、create table 時に data directory を指定して Block storage 上につくるようにする。作業が終わったらアンマウントして捨てる。<作業手順の改善>
  2. 作業②のバッチジョブ失敗時はデータ消去を試みるように仕様を変更した。また、データ消去にも失敗した場合はアラートを保守端末に通知するようにした。<実装の改善>
  3. そもそもデータベースサーバの空き容量が少なすぎる。<環境要因の排除>
    ⇛イベントポイント増加量の保持方法の正規化により、30GBのデータベース容量を削減し、空き容量を約90GBまで確保した。