rails-migration-safety について
実環境での Rails スキーマ変更を計画・レビューするスキルです。段階的なロールアウト、バックフィルとスキーマ変更の分離、ロック・デプロイ・復旧リスクの把握を重視します。
主な機能
- 01段階的なスキーマ変更の指針
- 02バックフィルとマイグレーションの分離
- 03インデックスとロックのリスク確認
- 04デプロイ順序の計画
- 05ロールバックと前方修正の計画
活用シーン
- 01デプロイ前の Rails マイグレーション確認
- 02大規模または高負荷テーブルの安全な変更
- 03カラム名変更とデータのバックフィル計画
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ midudev/ autoskills --skill rails-migration-safetyインストール後、Claude Code で/rails-migration-safetyを入力して読み込まれたか確認します。
同梱ファイルPATTERNS.md
詳細
Rails マイグレーションの安全性
実環境で安全なスキーマ変更が必要な場合に、このスキルを使用します。
基本原則: 大規模または高負荷のテーブルでは、一度に実行するマイグレーションより段階的なロールアウトを優先します。
クイックリファレンス
| 操作 | 安全なパターン |
|---|---|
| カラムの追加 | まず NULL 許容で追加し、後からバックフィルして、最後に NOT NULL を適用 |
| インデックスの追加(大規模テーブル) | algorithm: :concurrent(PG)/:inplace(MySQL) |
| データのバックフィル | マイグレーションのトランザクション内ではなく、バッチジョブを使用 |
| カラム名の変更 | 新しいカラムを追加し、データをコピーして、呼び出し元を移行し、古いカラムを削除 |
| NOT NULL の追加 | すべての行に値があることをバックフィルで確認した後 |
| 外部キーの追加 | 孤立レコードをクリーンアップした後 |
| カラムの削除 | 先にコード内の参照を削除し、その後カラムを削除 |
厳格な必須条件
DO NOT combine schema change and data backfill in one migration.
DO NOT add NOT NULL on a column that hasn't been fully backfilled.
DO NOT drop columns before all code references are removed.
レビューの順序
- データベースとテーブルサイズのリスクを特定します。
- スキーマ変更とデータのバックフィルを分けます。
- インデックス、制約、デフォルト値、テーブル再構築によるロックの挙動を確認します。
- アプリケーションコードとマイグレーションコードのデプロイ順序を計画します。
- ロールバックまたはフォワードフィックスの方針を計画します。
安全なパターン
- まず NULL 許容のカラムを追加し、後からバックフィルして、最後に
NOT NULLを適用します。 - サポートされている場合は、インデックスを並行して追加します。
- データ量が多い場合は、長時間のトランザクションの外でバッチ処理によりバックフィルします。
- 移行期間中、新旧どちらのスキーマでも動作するコードをデプロイします。
- カラム名の変更、型の変更、一意制約には複数段階のロールアウトを使用します。
プロジェクトで strong_migrations を使用している場合は、そのルールに従ってください。使用していない場合も、同じ安全ルールを手動で適用してください。
例
危険な例(避けてください):
add_column :orders, :status, :string, default: 'pending', null: false
Order.update_all("status = 'pending'")
- リスク: 長時間のロックが発生します。大規模テーブルにデフォルト値を適用すると、テーブルが再構築される可能性があります。
安全なパターン:
# Step 1: add nullable column
add_column :orders, :status, :string
# Step 2 (separate deploy): backfill in batches outside migration
# Step 3 (after backfill): add constraint
change_column_null :orders, :status, false
change_column_default :orders, :status, from: nil, to: 'pending'
大規模テーブルのインデックス:
# PostgreSQL: concurrent index (no write lock)
disable_ddl_transaction!
add_index :orders, :processed_at, algorithm: :concurrent
# MySQL: online DDL
add_index :orders, :processed_at, algorithm: :inplace
よくある間違い
| 間違い | 実際のリスク |
|---|---|
| 「テーブルが小さいので、段階的なマイグレーションは不要」 | テーブルは成長します。すべてのマイグレーションでこの習慣を身につけましょう。 |
| スキーマ変更とバックフィルを1つのマイグレーションにまとめる | トランザクションもロックも長時間に及びます。必ず分けてください。 |
| カラム名の変更と同時にアプリケーションを切り替える | デプロイ中にアプリケーションがクラッシュします。追加・コピー・移行・削除の順で行ってください。 |
algorithm: :concurrent を指定せずに add_index を使う | 大規模な PostgreSQL テーブルでは排他ロックが発生し、書き込みがブロックされます。 |
| バックフィル完了前に NOT NULL を追加する | マイグレーションが失敗するか、バックフィルを待つ間、テーブルがロックされます。 |
| コード内の参照を削除する前にカラムを削除する | 存在しないカラムにアクセスした際に、アプリケーションがクラッシュします。 |
危険信号
- スキーマ変更とデータのバックフィルを、1つの長時間マイグレーションにまとめている
- アプリケーションコードが即時切り替えを前提としたカラム名の変更
- 大規模テーブルに対するデフォルト値、テーブル再構築、NOT NULL の変更に段階的な計画がない
- 既存データをクリーンアップする前に外部キーまたは一意制約を追加している
- 置き換え先の処理と同じデプロイで、破壊的な削除またはドロップを行っている
- ロールバックまたはフォワードフィックスの方針が文書化されていない
出力スタイル
最初にリスクを列挙します。
各リスクには、次の項目を含めます。
- マイグレーションの手順
- 想定される失敗モードまたはロックのリスク
- より安全なロールアウト
- ロールバックまたはフォワードフィックスに関する注意点
複雑な型変更、複数段階での一意制約の追加、外部キー検証の延期、安全なカラム削除、複数データベースのマイグレーションについては、PATTERNS.md を参照してください。
連携
| スキル | 連携するタイミング |
|---|---|
| rails-code-review | マイグレーションを含む PR をレビューする場合 |
| rails-background-jobs | スキーマ変更後に実行するバックフィルジョブの場合 |
| rails-security-review | マイグレーションで機密データを公開または移動する場合 |
コメント
Markdown 対応