[AWS] RDSがなんかやたら遅い時に確認すること

2025/10/13

AWS
RDS

こんにちは。

今回は、原因不明で、突如なんかやたらRDSが重くなったときのことを話します。

早速主題

原因は、gp2のBurstBalanceが死んだことでした。

ここからは、発生当日に残したメモを整理しつつ流れを振り返ります。


何が起きてたか(現場メモ)

  • 現象:ECSのデプロイ後にアプリが500系エラーを連発
  • ログ:コンテナの entrypoint で実行するDBスキーマ変更(マイグレーション)がタイムアウトで落ちる
  • RDSBurstBalance0% に張り付き、I/O がベースラインまで絞られて激遅
  • 背景:ちょうど同じタイミングで 定期バッチ が走っており、I/O を食い散らかしていた疑い

つまり「I/O が出ない状態で重い DDL/マイグレーションを踏んだ → タイムアウト → 起動失敗 → 500」というシンプルな流れでした。


まずやったこと(時系列)

  1. ECSのタスクログをチェック
    → entrypoint 内のスキーマ変更がタイムアウトで落ちていることを確認
  2. CloudWatch の RDS メトリクスを確認
    BurstBalance0%DiskQueueDepth は盛り盛り、Read/WriteIOPS はベースラインで頭打ち
  3. 「これはクレジット枯渇だ」と判断
    アプリのバグではなく DB I/O の詰まりが主因と確信
  4. RDS ストレージを一時的に gp3 へ切り替え
    → 体感 10分程度で復旧(500 が止まり、マイグレーションも完走)

超ざっくり:BurstBalanceって何?

gp2 は容量に応じた ベースライン IOPS が決まっていて、短期的には バーストで速くできる仕組みです。ただしクレジットは有限で、使い切ると急にベースラインへ落ちる

普段は気づきにくいのですが、バッチ + デプロイ(DDL) のように I/O の山が重なると一気に枯れます。今回はまさにその瞬間に重い DDL が刺さった形です。


なんで 500 になったの?

  • コンテナ起動時(entrypoint)で DDL/マイグレーション を走らせている
  • その瞬間、RDS が I/O を絞られた低速モード(Burst 0%)に突入
  • DDL が待ち行列に積まれて時間切れ → entrypoint 失敗 → コンテナ不健康 → 500

「アプリが悪い」というより「環境が DDL を許さないタイミングに当たった」が実態でした。


対応:とりあえず gp3 に

  • gp3 は容量に依存せず 一定の IOPS/スループット を確保できるので、「クレジット枯渇で急降下」がありません。
  • 今回は一時的に gp3 にスイッチ約 10 分で回復
    以後 500 は消え、マイグレーションも完了。

余談:コスト的にも gp3 は悪くないので、そのまま gp3 運用でも十分アリだと思っています。


なぜ 10 分で戻った?(個人の推測)

  • ストレージタイプ変更の適用で I/O の頭打ちが解消
  • 直近の I/O 山場(バッチ)が終わり、待ち行列が掃けた
  • アプリはリトライ/再起動で自然回復ラインに乗った

要は「I/O を出せる状態に戻す」が一番効いた、という感触です。


次回の自分へのメモ(再発防止)

運用系

  • CloudWatch アラーム
    • BurstBalance < 50% で通知
    • DiskQueueDepthFreeStorageSpaceRead/WriteLatency も閾値設定
  • バッチのスケジューリング見直し
    • デプロイ時間とかぶらせない
    • 大量処理は分割 or レプリカで読む
  • 可能なら常時 gp3
    • 「静かな時は爆速、混むと地獄」の振れ幅をなくす

アプリ/DB系

  • エントリポイントで重い DDL を叩かない(段階適用・メンテ時間を設ける・リトライ/バックオフを設計)
  • マイグレーションは
    • ロック時間が短い手順に分ける
    • インデックス追加は CONCURRENTLY 相当(MySQL はやり方に注意)
    • 長時間フルスキャンが走る変更は事前検証を徹底

最後の切り札

  • gp2 を続けるなら、容量を増やしてベースライン IOPS を底上げ(コストとのトレードオフ)

まとめ

  • 症状:デプロイ後に 500 連発 → 実はDB I/O が枯渇
  • 原因gp2 の BurstBalance 0%(バッチとタイミングが悪かった)
  • 対応gp3 に切り替え → 体感 10 分で回復
  • 教訓:I/O の山が重なる設計は避ける。監視とアラートを早めに仕込む。重い DDL は踏むタイミング手順を慎重に。

この辺りをテンプレ化しておけば、次に「なんか急に RDS が重い…」が来ても落ち着いて捌けるはずです。

Related Posts

[AWS] GenU(Generative AI Use Cases JP)でAWS × 生成AI入門してみた

[AWS] GenU(Generative AI Use Cases JP)でAWS × 生成AI入門してみた

[AWS] AWS CDKでNext.jsのSSGでCloudFrontとS3にデプロイする

[AWS] AWS CDKでNext.jsのSSGでCloudFrontとS3にデプロイする

[AWS] AWS Amplify Gen2がやばい。これからのサービス立ち上げ全部これでいいじゃん。

[AWS] AWS Amplify Gen2がやばい。これからのサービス立ち上げ全部これでいいじゃん。