コンテンツにスキップ

DBスキーマ変更をオンラインで安全に行うための仕組み

チェック

  • [ ] 本文を確認した
  • [ ] 概要を確認した
  • [ ] タグを確認した
  • [ ] inbox/ 直下へ移行した

概要

SmartBank が Rails / ridgepole 環境で、外部の Online Schema Change tool を追加せずに DB schema change を安全化した事例。 危険な DDL による metadata lock や MySQL ALTER algorithm の問題を、CI での DDL algorithm 検知、lock_wait_timeout 設定、foreign_key_checks の一時無効化で抑制している。 PR 上で DDL の危険度を可視化し、開発者が事前に判断できるようにしている。

本文

オンラインスキーマ変更には pt-oscgh-ost があるが、Rails 標準 migration や ridgepole を使う現場では、追加 tool の運用負荷も大きい。 SmartBank では ridgepole を使った宣言的 schema 管理に移行しており、strong_migrations をそのまま使えなくなった。

最初は PR comment に DDL と注意文言を出していたが、それだけでは不十分だった。 開発者の変更によって意図しない metadata lock や危険な ALTER algorithm が採用され、一部 request が失敗する小さな障害が発生した。

そこで 3 つの対策を導入した。

  1. DDL algorithm 検知
  2. timeout 設定
  3. foreign key check 無効化

DDL algorithm 検知では、CI 上で ridgepole を ALGORITHM=INSTANTALGORITHM=INPLACE の順に試し、どちらも失敗したら COPY と判定する。 危険度は、INSTANT が低、INPLACE が中、COPY が高。 PR comment で危険度と推奨対応を表示する。

timeout では、MySQL の lock_wait_timeout が default で 1 年相当と非常に長いため、ridgepole 実行時に SET SESSION lock_wait_timeout=5 を指定する。 これにより metadata lock 待機が長引く前に DDL を失敗させられる。

foreign key 追加では、MySQL default の foreign_key_checks=1 だと COPY algorithm になるため、ridgepole 実行時に SET SESSION foreign_key_checks=0 を使い、INPLACE を採用させる。 ただし外部キー制約違反の混入リスクはあるため、アプリケーション側で整合性を担保する設計にしている。

要点

  • DDL の危険度は PR 前に CI で可視化できる。
  • MySQL の lock_wait_timeout default は DDL 運用には長すぎる。
  • INSTANT / INPLACE / COPY の違いを開発者が見える状態にする。
  • 外部 tool を増やさず、ridgepole と session 設定でも安全性を上げられる。

タグ

database #mysql #rails #migration #ridgepole