GitLab.comのデータベース障害から学ぶ post

(最終更新:2017/02/15)

2017/01/31、GitLab.comでデータベース障害が発生し、サービスの停止および約6時間分のデータベースのデータ(projects、 issues、comments、snippetsなど)が消失しました。

なお、Gitリポジトリに障害はなく、リポジトリのコンテンツ(Wikiを含む)にデータ消失はありませんでした。

GitLab.comとは?

GitLab.comはGitLab社が提供しているGitHubのようなGitリポジトリのホスティングサービスです。無料でプライベートリポジトリも使えます。

タイムライン

日時(UTC) 出来事
2017/01/31 23:27 GitLab.com、オペレーションミスにより本番データベースのデータを削除。サービス停止
2017/01/31 23:28 データベースの緊急メンテナンス中である旨をツイート
2017/02/01 00:00 約6時間前のスナップショットをリストアすることを決定
2017/02/01 00:44 Google Docsでのライブの状況報告についてツイート
2017/02/01 11:42 YouTubeでの復旧作業のライブストリームについてツイート
2017/02/01 18:14 GitLab.com復旧
2017/02/10 Postmortem(事後分析)公表

透明性

今回のGitLabのインシデント対応で際立ったことは、迅速な報告と透明性です。

恐ろしく早く状況が詳細にGoogle Docsで報告されていき、ついに復旧作業がYouTubeでライブで流されました。

データバックアップは失敗したのか?

データベースの消失は、複数のインシデント対応中にオペレーションミスが発生し、本番のPostgreSQLデータベースのデータディレクトリが削除されたことによります。

GitLabは事前に以下のバックアップ手段を講じていました。

  1. 24時間ごとのデータベースダンプ(pg_dump)
  2. データベースダンプのS3へのバックアップ
  3. 24時間ごとのAzureのディスクスナップショット
  4. 24時間ごとのLVMスナップショット
  5. PostgreSQLのレプリケーション

しかし、実際には、

5.のレプリケーションはもともとリカバリ目的ではなくフェイルオーバーのためのものであり、厳密にはバックアップとは言えません。また、そもそもレプリケーションを再構築する途中で結果的に今回のインシデントが発生しています。障害発生時にはレプリケーションにはすでにデータはありませんでした。

1.のデータベースダンプは、pg_dumpのバージョンが9.2と古く、実際のデータベースはPostgreSQL 9.6だったため、エラーでダンプが取得できていませんでした。そのため、2.のS3へのバックアップも当然空でした。

3.のAzureのディスクスナップショットはNFSサーバでは取得されていましたが、データベースサーバでは取得されていませんでした。また、仮にスナップショットがあったとしても、ディスクスナップショットから一部のファイル(データベースファイル)をリストアすることは簡単ではありません。

4.のLVMスナップショットは機能していましたが、障害の6時間前に手動で取得された別のスナップショットがありました。そのため、今回は6時間前のスナップショットからリストアされました。

つまり、いろいろとバックアップに不具合はありましたが、それでも最悪24時間前の状態にはLVMスナップショットから戻れたということになります。

仮にすべてのバックアップ手段が正常に機能していたとしても、データベースダンプは最大24時間前のものですし、ディスクスナップショットも最大24時間前です。

このことから、リカバリ要件は最大24時間のデータロスを前提としていたと考えられます。そして、少なくとも24時間前のLVMスナップショットがあったことから、その時点への復旧は可能でした。

結論としては、今回のインシデントに関しては、バックアップは要件を満たして機能していたことになると思います。

重要なのはリカバリ要件

もし、24時間のデータロスが許容できないのであれば、それはリカバリ要件が間違っていたということになります。

また、リカバリ要件には復旧時間もありますので、そちらの要件はたぶん満たせていなかったのでしょう。Postmortemには、復旧に18時間以上かかったことが問題であるとされています。

Postmortem(事後分析)

事前に予告されていた通り、GitLabからPostmortemが02/10に公表されました。

根本原因分析(なぜなぜ分析)やリカバリ手順の改善など、非常に興味深い内容が含まれています。是非、お読み下さい。

データディレクトリが削除された原因は、レプリケーションの再構築手順が自動化されておらず、また、作業のドキュメントもきちんと作成されていなかったからとされています。

バックアップ手順が検証されていなかった原因については、責任者が決まっていなかったことがあげられています。

まとめ

こうして見ると、今回の障害はリカバリ要件の定義やバックアップやリストア手順の設計により根本的な問題があったことがわかります。要するに事前の分析検討や準備計画が不十分だったということです。

  • リカバリ要件が不明か誤ってる
  • バックアップの責任者がいない
  • バックアップからリストアできるか検証されていない
  • バックアップが正常に取得できているかの監視がない
  • レプリケーション再構築の手順書が不十分
  • 複雑な作業を一人で行う運用
  • 間違いやすそうな似たようなサーバ名(db*.cluster.gitlab.com)

障害の直接の原因は、担当者が誤ってデータベースのデータディレクトリをrmしてしまったことですが、それは単なるきっかけにすぎないことがわかります。

参考

GitLabからのデータベース障害に関する報告:

GitLabの緊急対応マニュアル:

PostgreSQLのコミッタからのアドバイス:

この障害に関する記事:

Date: 2017/02/14

Tags: postgres, gitlab, incident