1. Cloud SQL の事故ケース
事故 1.1 — ストレージ枯渇による DB ダウン 高頻度
症状: アプリから「Disk full」エラーが噴出し、DB が書き込み不可。読み取りは可能だが、新規トランザクションは即時失敗。
典型ケース: バイナリログ + 日次バックアップで予想以上にストレージが消費、ストレージ自動増加を無効にしていた。
Root Cause:
Storage auto increase を無効化(コスト懸念で)
- binary log の保持期間が PITR 35日に設定されていた
- 監視アラートが 80% で設定されており気付いたが、増加スピードに対処が遅れた
再発防止:
- Storage auto increase は必ず有効化(縮小は不可だが、ダウンよりはマシ)
- アラート閾値を「使用率 + 増加率」の 2 軸で設定(例: 70% & 24h で +10% 増)
- 不要な binary log を定期的に整理(ただし PITR 期間内は削除不可)
- テーブル毎の容量を
information_schema.tables で週次監査
事故 1.2 — メジャーアップグレード後ロールバック不可 高頻度
症状: PostgreSQL 13 → 15 にインプレースアップグレード後、アプリが collation エラーで起動不可。ロールバック手段がなく緊急復旧でダウンタイム拡大。
Root Cause: PostgreSQL はメジャーバージョン間で collation 定義が変わる場合があり、既存インデックスが破損して動かない。
Cloud SQL のインプレースアップグレードは 「成功したらロールバック不可」が公式仕様。
再発防止:
- メジャーアップグレードは Blue-Green + DMS で並行構築
- テスト環境で
REINDEX 必要性を事前確認
- アプリの全 SQL クエリを新バージョンで
EXPLAIN
- 切り戻し用に旧バージョンインスタンスを 1 ヶ月維持
事故 1.3 — Cross-region Replica 昇格後のスプリットブレイン 中頻度
症状: 旧 Primary リージョンが復旧した際、旧 Primary とプロモートした新 Primary の両方に書き込みが入り、データ不整合が発生。
Root Cause: クロスリージョン リードレプリカは 手動 Promote。Promote 後、旧 Primary は自動でレプリカに戻らず孤立。DNS / Load Balancer が旧 IP を引いていた場合、一部トラフィックが旧へ流れる。
再発防止:
- Promote 直後に旧 Primary を停止(trafficが入らないよう物理的に遮断)
- アプリは 接続文字列を集中管理(Secret Manager / Config Server)
- DNS TTL を短く(60秒以下)して切り替えを高速化
- 切り戻し計画書を事前に作成し、訓練
事故 1.4 — サーバーレスからの接続枯渇 高頻度
症状: Cloud Run のオートスケールが効くピーク時、Cloud SQL が too many connections エラーで応答不可。
Root Cause: Cloud Run の各インスタンスがそれぞれ DB プールを持ち、合計接続数が max_connections を超過。サーバーレスの特性で瞬時にスケールするため検知が遅い。
再発防止:
- 外部コネクションプーラー導入(PgBouncer on Cloud Run sidecar、AlloyDB 組み込みプーラー)
- Cloud SQL Auth Proxy の
--max-connections 上限設定
- アプリ側でプールサイズを小さく(インスタンス毎に 5-10)
- Memorystore でセッションキャッシュ → DB アクセス頻度削減
事故 1.5 — CMEK 鍵削除によるインスタンス停止 低頻度・致命的
症状: Cloud KMS で「不要だと思った鍵」を削除したところ、その鍵で暗号化された Cloud SQL が即時停止。
Root Cause: CMEK 鍵が無効化/削除されると、Cloud SQL はマウントしている永続ディスクを復号できず、即時停止。鍵の使用状況がアラートになっていなかった。
再発防止:
- Cloud KMS の鍵削除は destroy schedule(最低24時間〜30日)で猶予を持つ
- 鍵削除前に
gcloud kms keys list-revoked + 利用先を必ず確認
- 本番用 KMS 鍵は 専用プロジェクト + 限定 IAM で管理
- KMS の Cloud Monitoring アラートで「decrypt 操作の急減」を検知
2. AlloyDB の事故ケース
事故 2.1 — Read Pool が Primary より大幅に遅延 中頻度
症状: アプリが「直前に書いたデータが Read Pool で読めない」と苦情。レプリ遅延が数秒〜数十秒に拡大。
Root Cause:
- Primary で大量バッチ書き込みが走り、Read Pool の WAL 適用が追いつかない
- Read Pool ノードのリソース不足
- 大規模 ALTER TABLE が走り、レプリがブロック
再発防止:
- 「直近書き込みを即座に読む」必要があるクエリは 明示的に Primary に投げる(アプリで使い分け)
- 大規模 DDL は メンテナンスウィンドウで実施
- Read Pool のレプリ遅延 (
replication_lag) を Cloud Monitoring でアラート(30秒)
- バッチ書き込みは 分割コミット でレプリへの負荷を均す
事故 2.2 — Columnar Engine 有効化後に CPU 高騰 中頻度
症状: Columnar Engine を有効化した直後、Primary のメモリ使用率が急上昇し、OLTP クエリのレイテンシ悪化。
Root Cause: Columnar Engine は列ストアを In-memory で構築するため、メモリを消費する。これが OLTP の buffer pool を圧迫した。
再発防止:
google_columnar_engine.memory_size_in_mb でメモリ上限を明示
- 列対象テーブルを Recommended Tables 機能で必要最小限に絞る
- Columnar 有効化はRAM に余裕のあるマシンタイプへ変更後に実施
- OLTP と分析が両方重要なら Read Pool に Columnar、Primary は無効の分離
事故 2.3 — Secondary Cluster Switchover 時のデータロス 低頻度・致命的
症状: プライマリリージョン障害で Secondary Cluster を Switchover したが、直前数秒の書き込みが失われた。
Root Cause: Secondary Cluster は非同期レプリのため、Primary 障害時に WAL が伝播していない数秒分のデータが消失する可能性がある(RPO > 0)。
再発防止:
- 「RPO=0 が必要」なら AlloyDB Secondary ではなく Spanner Multi-region を選定
- レプリ遅延を継続監視し、遅延が大きければアプリで「書き込み確認後にレスポンス」を強制
- 重要トランザクションは二重書き込み(外部 Kafka / Pub/Sub)で保険
3. Spanner の事故ケース
事故 3.1 — 連番主キーによるホットスポット 高頻度
症状: 移行直後は順調だったが、データ量増加とともにレイテンシが線形に悪化。1 ノード追加しても性能改善せず。
Root Cause: Cloud SQL から移行する際に SERIAL 相当の連番 ID を主キーにした。Spanner では末尾スプリットに書き込みが集中し、ノード追加しても 1 ノードしか働かない。
再発防止:
- Spanner 主キーは UUID v4 / hash-prefixed / 反転タイムスタンプのいずれか
- 移行前にスキーマレビュー、特に主キー設計を Spanner 公式の Schema design best practices で確認
- Key Visualizer (Spanner 版) で書き込み分布を可視化
- 連番 ID が業務上必要なら シーケンステーブル + hash プレフィックスで分散
事故 3.2 — Multi-region のクエリレイテンシ予想以上 中頻度
症状: Regional から Multi-region に移行したら、書き込みレイテンシが 40ms → 150ms に増加。
Root Cause: Multi-region は複数リージョンの Paxos voter から quorum を取る必要があり、最寄り 2 voter の応答待ち(地理的に近くないと数十 ms 増加)。
再発防止:
- Multi-region は SLA 99.999% が必要なケースのみ。それ以外は Regional
- Read-only Replica を地域別に配置して読み取りレイテンシ最小化
- Default leader region をユーザー多数の地域に設定
- Multi-region 移行前に Regional の Cross-region Backupで代替できるか検討
事故 3.3 — Strong Read で予想以上のレイテンシ 中頻度
症状: Spanner の全クエリで Strong Read を使ったらコストとレイテンシが想定の 2 倍。
Root Cause: Strong Read は常に最新の commit timestamp を取得するため、Paxos quorum の応答を待つ。Stale Read(数秒の遅延許容)の方が低コスト・低レイテンシ。
再発防止:
- 強整合が必要なクエリだけ Strong Read
- 分析・ダッシュボード用は Stale Read (10秒) で十分
- Stale Read は Read-only Replica で処理されコスト削減
4. Bigtable の事故ケース
事故 4.1 — Hot Tablet による全クラスタ性能劣化 高頻度
症状: 朝 9 時のピーク時に Bigtable のレイテンシ p99 が 100ms 超え。Key Visualizer で 1 つの行範囲が真っ赤。
Root Cause: 行キーに「センサーID_タイムスタンプ昇順」を使っていた。同センサーの全書き込みが 1 Tablet に集中。
再発防止:
- 行キー再設計(hash プレフィックス、reverse timestamp)
- 変更不可能な既存テーブルは 別テーブルに移行 + デュアル書き込み
- Key Visualizer を週次で確認
- 新規スキーマは事前に
cbt で書き込みテスト → Key Visualizer 確認
事故 4.2 — マルチクラスタ ルーティングで結果整合エラー 中頻度
症状: 「書いた直後に読めない」事象が発生。ユーザー登録→直後ログインで「ユーザー未存在」エラー。
Root Cause: マルチクラスタ ルーティングは eventual consistency。アプリは別クラスタから読みに行く可能性がある。
再発防止:
- 「書いた直後に読む」操作は Single-cluster routing or Row-affinity routing の App Profile を使う
- App Profile を業務毎に分離(ログイン用、分析用、バックエンド用)
- クライアントで
read-your-writes パターンを実装(ローカルキャッシュ)
事故 4.3 — SSD → HDD への変更不可で大規模移行 低頻度・大規模
症状: コスト削減のため SSD クラスタを HDD に変えたかったが、ストレージタイプ変更不可と判明。新クラスタ作成・データ全移行・アプリ切り替えで 3 週間の工数。
再発防止:
- クラスタ作成時に SSD/HDD を慎重に選択(変更不可)
- 用途別にクラスタ分離(リアルタイム=SSD、アーカイブ=HDD)
- 必要に応じてマルチクラスタ + レプリで HDD クラスタに分散
5. Firestore の事故ケース
事故 5.1 — 課金爆発(リアルタイムリスナー過剰) 高頻度
症状: 月 $200 の予算が、1 日で $5,000 を超える請求アラート。
Root Cause: アプリのバグで「ページロード毎にリスナーを張り直し、解除しない」コードが本番投入。各リスナーが大量のドキュメント変更通知を発生させ read オペレーション課金が爆発。
再発防止:
- Budget Alert を「予算の 50/80/100%」で 3 段設定
- 本番デプロイ前に Firestore Emulator で課金見積もり
- リスナーは
unsubscribe を必ず実装、useEffect cleanup を徹底
- クエリ毎の
limit() 必須化
- Cloud Logging で「read 数 / hour」が異常に増えたらアラート
事故 5.2 — Security Rules 不備で全データ漏洩 低頻度・致命的
症状: Firestore のセキュリティスキャナで「全ドキュメントが匿名ユーザーから読み取り可能」と通知。
Root Cause: 開発初期の allow read, write: if true; を本番に持ち込んだ。
再発防止:
- 本番 deploy 前に
firebase deploy --only firestore:rules のレビュー必須
- Security Rules の単体テスト(
@firebase/rules-unit-testing)
- 「Test mode」での deploy を CI でブロック
- Firestore のセキュリティスキャナを継続有効化
事故 5.3 — 500/50/5 ルール違反で書き込み失敗 中頻度
症状: バッチでデータ投入したら、途中から書き込みが失敗。
Root Cause: 新規 Collection への持続的書き込みは 500 ops/sec が初期上限。これを 5 分毎に 50% ずつ増加させる必要がある。
再発防止:
- 大量初期投入は 500 ops/sec → 5分後 750 → ... で徐々に増加
- 事前に空ドキュメント書き込みでウォームアップ
- 書き込み量が大きい場合は Bigtable に変更
6. Memorystore の事故ケース
事故 6.1 — Basic Tier 再起動でセッション全消失 高頻度
症状: Memorystore Basic Tier のメンテナンスで再起動 → 全ユーザーが強制ログアウト、苦情殺到。
Root Cause: Basic Tier は HA なし・永続化なし。再起動でメモリ上のセッションデータが全消失。
再発防止:
- 本番セッションストアは Standard Tier 以上(HA + replication)
- セッションは Firestore か Cloud SQL に永続化 + Redis にキャッシュ
- Basic Tier は「再構築可能なキャッシュ」専用
事故 6.2 — TTL 設定忘れでメモリ満杯 高頻度
症状: Redis が OOM command not allowed エラーで書き込み拒否。
Root Cause: アプリが SET key value だけで EX(TTL)を付けず、データが無限に蓄積。
再発防止:
- すべての
SET に TTL 必須化(コードレビュー or ラッパー関数)
maxmemory-policy を allkeys-lru に設定(古いデータから自動削除)
- メモリ使用率 85% でアラート
- キー命名規則を統一して用途別 TTL を可視化
事故 6.3 — Big Key による全 Redis 停止 中頻度
症状: 1 キーの値が数十 MB に膨れ上がり、そのキーへのアクセスで Redis 全体が応答停止。
Root Cause: Redis はシングルスレッド。1 つの大きな値の読み取りが全体をブロック。
再発防止:
- 1 キー = 100KB 以下を原則
- 大きいデータは分割キー(user:123:item:0, user:123:item:1...)
SCAN + STRLEN で定期的に big key 検出
- 大きいオブジェクトは GCS に逃がして Redis には URL のみ
7. DMS の事故ケース
事故 7.1 — binlog 削除でレプリ中断 高頻度
症状: MySQL → Cloud SQL の DMS Continuous で、ある日突然レプリが失敗。「binlog file not found」エラー。
Root Cause: ソース MySQL の expire_logs_days が 1 日。DMS のレプリ遅延が大きくなった日に、適用前の binlog が削除されてしまった。レプリ復旧不可、初期 Dump からやり直し。
再発防止:
expire_logs_days はレプリ遅延の最悪値 + 余裕で設定(最低 7 日)
- レプリ遅延を継続監視、遅延 1 時間でアラート
- binlog ストレージ容量も監視(保持期間延長でディスク不足を防ぐ)
事故 7.2 — PK 非保有テーブルで UPDATE 同期されず 中頻度
症状: 移行完了後、新 DB と旧 DB のデータ件数は一致するが、内容が異なるレコードが多数。
Root Cause: 一部のテーブルに Primary Key がなく、DMS の CDC では INSERT のみ反映。UPDATE / DELETE が無視されていた。
再発防止:
- 移行前に
SELECT で全テーブルの PK 有無を監査
- PK のないテーブルには サロゲートキーを事前付与(移行前作業)
- 移行後にチェックサム比較
- DMS のジョブログで「Replication mode: insert only」警告を必ず確認
事故 7.3 — カットオーバー時のデータロス 低頻度・致命的
症状: アプリ書き込み停止が早すぎ、Promote 時にまだ送られていない transaction が旧 DB に残ってロスト。
Root Cause: 残ログ適用完了の確認なしで Promote ボタンを押した。
再発防止:
- カットオーバー手順をチェックリスト化(残ログサイズ = 0 を確認、レプリ遅延 < 1秒)
- ステージング環境でカットオーバーのドライランを必ず実施
- 当日は 2 人体制(操作者 + 確認者)
- リバースレプリケーション保険で初期化(数日〜数週間)
8. Datastream の事故ケース
事故 8.1 — Oracle LogMiner の負荷でソース DB 性能劣化 中頻度
症状: Datastream を有効化したら、オンプレ Oracle の CPU 利用率が 30% → 80% に上昇、OLTP のレイテンシ悪化。
Root Cause: Oracle LogMiner ベースの CDC はredo log の解析でソース DB に負荷がかかる。大量の DML がある DB ほど顕著。
再発防止:
- Oracle ソースは LogMiner より GoldenGate 連携を検討(追加コストあり)
- Datastream 有効化は OLTP オフピーク時間に
- ソース DB の CPU 余裕を 30% 以上残す
- 必要に応じてソース DB を読み取り専用スタンバイに変更
事故 8.2 — スキーマ変更が BigQuery に伝播せずクエリ失敗 中頻度
症状: ソース DB で ALTER TABLE ADD COLUMN を実施 → BigQuery で「column not found」エラー。
Root Cause: Datastream の DDL 伝播は限定的。複雑な ALTER は手動で BigQuery 側も対応必要。
再発防止:
- DDL 変更プロセスを変更管理に組み込み(CR で BigQuery 側の対応も含める)
- BigQuery テーブルの
information_schema.columns を週次で diff
- シンプルな列追加なら自動伝播するが、複雑なものは要事前テスト
事故 8.3 — Datastream ストリーム停止に気付かず分析データが古いまま 中頻度
症状: 営業会議で「今日の売上 0 円」と報告 → 実は Datastream ストリームが 3 日前に停止していた。
Root Cause: ストリーム停止時のアラート設定なし。BigQuery には古いデータが残っているため気付きにくい。
再発防止:
- ストリーム状態 (
state=FAILED/PAUSED) を Cloud Monitoring でアラート
- BigQuery 側に「最終更新時刻」テーブルを作り、定期的に古さを監視
- BIダッシュボードに「データ鮮度(X分前更新)」を必ず表示
9. 全DB横断の事故パターン
パターン A: コスト爆発
共通原因:
- 従量課金 (Firestore, Spanner, BigQuery, Datastream) で予測外の使用
- 本番投入前のテストでコスト見積もりを怠る
- Budget Alert を設定していない、または閾値が高すぎる
横断対策:
Budget Alert を必ず 3 段(50/80/100%)で設定、定期コストレビュー、夜間や開発環境はリソース削減
パターン B: 「マネージドだから大丈夫」過信
共通原因: GCP マネージド DB を「障害も自動で対応してくれる」と思い込み、ヘルスチェック・アラート・Runbook を準備しない。
横断対策: マネージドでも SLO/SLI を自前で測定、Runbook 作成、年 1 回の障害訓練(DR ドリル)
パターン C: 開発環境と本番環境の差
共通原因:
- 開発は ZONAL (HA なし)、本番は REGIONAL HA → 挙動が異なる
- 開発は Public IP、本番は Private IP → 接続設定が異なる
- 開発はマシンタイプが小さい → 性能問題が本番だけで発生
横断対策:
Terraform で構成共通化、本番相当の
ステージング環境を維持
パターン D: 移行・アップグレード時の事故
共通原因: メジャーバージョンアップやリージョン移行で「テスト不足」「ロールバック計画不在」。
横断対策: Blue-Green パターン、ステージング ドライラン、切り戻し計画書を運用標準化
パターン E: バックアップが取れていなかった
共通原因: バックアップは取っているが、復元テストをしていない。いざ復元したら破損していた。
横断対策: 四半期に 1 回、別環境にバックアップから復元 + 整合性検証
📋 試験での出題傾向
PCDBE 試験では、上記の事故ケースを
シナリオ問題として出題することが多い。
- 「こういう症状が出ています。原因は?」 → Root Cause を選ぶ
- 「こういう状況を防ぐには?」 → Best Practice を選ぶ
- 「移行プロジェクトで失敗する典型的な理由は?」 → 横断パターンが答え
本ページの事故ケースを
「現場で見た / 自分が起こしうる事故」として読むと、シナリオ問題が解きやすくなる。