ざっくりGCP料金計算

バックアップ未設定のCloud SQLのデータが消えた話

「自動バックアップはデフォルトで有効なはず」という思い込みが、あの夜の教訓になった。

誤操作でテーブルをDROPした夜

深夜のメンテナンス作業中に、誤ってテーブルをDROPしてしまった。接続先が本番DBだということを確認せずにSQL文を実行した。DROP TABLE文は即座に完了し、数百万件のレコードが消えた。「まあバックアップから復元すれば大丈夫」と思いながら復元操作を始めようとしたとき、バックアップが存在しないことに気づいた。

Cloud SQLの自動バックアップはデフォルトで有効になっている——と思っていた。正確には「GCPコンソールからインスタンスを作成した場合は有効」だが、Terraformで作成したインスタンスはTerraformのコードで明示的に設定する必要がある。自分たちはTerraformでCloud SQLを管理していたのだが、参考にしたサンプルコードが「コスト最適化のためバックアップ無効化」という設定になっていた。それをそのまま使い続けていた。

復元できないデータと手動の再構築

DROPしたテーブルのデータの一部は別システムのDBに元データが存在していた。残りはCSVで出力したデータが手元に残っていた。それらを使って手動でデータを再構築する作業を開始した。データの整合性チェックも含めて、元通りになるまで丸1日かかった。開発チームのメンバー全員が深夜から翌朝にかけて対応に当たった。「もし別システムにデータがなかったら」「もしCSVのバックアップを誰かが取っていなかったら」と思うと、今でも背筋が寒くなる。コスト削減のために数百円を節約したバックアップ設定が、最悪の場合には事業継続を脅かすリスクを生んでいた。

バックアップ設定の見直しと定期的なリストアテスト

この件の後、TerraformのモジュールでCloud SQLインスタンスを作成するテンプレートでは自動バックアップとPITR(ポイントインタイムリカバリ)が必ず有効になるようにした。バックアップを無効にする設定は書けないように変数を削除した。合わせて「バックアップから実際に復元できるか」の定期テストを半年に1回実施するルールを設けた。バックアップが取れていることと、復元できることは別の問題だ。Cloud SQLのバックアップからの復元操作を一度もやったことがなければ、有事のときに慌てる。テスト環境でのリストア確認を「インフラ定期メンテナンス」のチェック項目に加えた。バックアップの費用はDB容量の数十%分のストレージコストであり、本番DBの保険と考えれば決して高くない。