mcpField
M
migration-planner

migration-planner

github.com/patricio0312revデータ・データベース63267 回インストール41 週間前に更新
リポジトリ

migration-planner について

本番環境の移行を担当するチーム向けに、停止時間を抑えた移行を計画するスキルです。段階的な展開、検証、リスク対策、ロールバックを整理します。

主な機能

  1. 01フィーチャーフラグとブルーグリーン方式
  2. 02デュアルライトとバックフィルの計画
  3. 03データ検証戦略
  4. 04フェーズ別ロールバック計画
  5. 05リスクと連絡計画

活用シーン

  1. 01データベース移行の計画
  2. 02読み取りトラフィックの段階的切り替え
  3. 03検証とロールバック手順の準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/patricio0312rev/skills --skill migration-planner

インストール後、Claude Code で/migration-plannerを入力して読み込まれたか確認します。

詳細

移行プランナー

検証とロールバック計画を備えた、安全でダウンタイムゼロの移行を実行します。

移行パターン

1. フィーチャーフラグによる移行(最も安全)
Phase 1: Deploy new code (disabled)
Phase 2: Enable for 1% traffic
Phase 3: Ramp to 10%, 50%, 100%
Phase 4: Remove old code
2. デュアルライトによる移行
Phase 1: Write to both old and new
Phase 2: Backfill old → new
Phase 3: Read from new (write both)
Phase 4: Stop writing to old
Phase 5: Decommission old
3. ブルーグリーンデプロイ
Blue (current) → Green (new)
Switch traffic: Blue → Green
Rollback available: Green → Blue

完全な移行計画テンプレート

# Migration Plan: MySQL → PostgreSQL

## Overview

**What:** Migrate user database from MySQL to PostgreSQL
**Why:** Better JSON support, improved performance
**When:** Q1 2024
**Owner:** Database Team
**Risk Level:** HIGH

## Current State

- MySQL 8.0
- 500GB data
- 100K users
- 1000 writes/min
- 10,000 reads/min

## Target State

- PostgreSQL 15
- Same data model
- No downtime
- Data validation 100% match

## Phases

### Phase 1: Dual Write (Week 1-2)

**Goal:** Write to both databases

**Steps:**

1. Deploy PostgreSQL cluster
2. Create schema in PostgreSQL
3. Deploy dual-write code
4. Enable dual writes (MySQL primary, PostgreSQL secondary)

**Code:**

```typescript
async function createUser(data: CreateUserDto) {
  // Write to MySQL (primary)
  const mysqlUser = await mysql.users.create(data);

  // Write to PostgreSQL (secondary, fire and forget)
  postgres.users.create(data).catch((err) => {
    logger.error("PostgreSQL write failed", err);
  });

  return mysqlUser; // Still trust MySQL
}
```

検証:

  • PostgreSQL の書き込み成功率を監視する
  • 行数を毎日比較する
  • 差異が 0.1% を超えた場合にアラートを出す

ロールバック: PostgreSQL への書き込みを無効にする

フェーズ 2:バックフィル(第 3~4 週)

目標: 過去のデータをコピーする

手順:

  1. MySQL のスナップショットを取得する
  2. バックフィルスクリプトをバッチで実行する
  3. データの整合性を検証する
  4. 失敗した場合は自動的に再開する

スクリプト:

def backfill():
    last_id = get_last_migrated_id()
    batch_size = 1000

    while True:
        users = mysql.query(
            "SELECT * FROM users WHERE id > %s LIMIT %s",
            [last_id, batch_size]
        )

        if not users:
            break

        postgres.bulk_insert(users)
        last_id = users[-1]['id']
        save_checkpoint(last_id)

        time.sleep(0.1)  # Rate limit

検証:

  • 行数が一致すること
  • ランダムサンプルを比較する(1000 行)
  • チェックサムを比較する

ロールバック: PostgreSQL のデータを削除する

フェーズ 3:デュアルリード(第 5 週)

目標: PostgreSQL の読み取りを検証する

手順:

  1. シャドーリードのコードをデプロイする
  2. 両方から読み取る(MySQL をプライマリにする)
  3. 結果を比較する
  4. 不一致をログに記録する

コード:

async function getUser(id: string) {
  const mysqlUser = await mysql.users.findById(id);

  // Shadow read from PostgreSQL
  postgres.users.findById(id).then((pgUser) => {
    if (!deepEqual(mysqlUser, pgUser)) {
      logger.warn("Data mismatch", { id, mysqlUser, pgUser });
      metrics.increment("migration.mismatch");
    }
  });

  return mysqlUser; // Still trust MySQL
}

検証:

  • 不一致率が 0.01% 未満であること
  • PostgreSQL のクエリパフォーマンスが許容範囲であること

ロールバック: シャドーリードを削除する

フェーズ 4:読み取りトラフィックの切り替え(第 6 週)

目標: PostgreSQL から読み取る

手順:

  1. フィーチャーフラグを設定し、PostgreSQL から読み取る(トラフィックの 1%)
  2. エラーとレイテンシを監視する
  3. 段階的に増やす:1% → 10% → 50% → 100%
  4. 両方への書き込みは継続する

コード:

async function getUser(id: string) {
  if (featureFlags.readFromPostgres) {
    return postgres.users.findById(id);
  }
  return mysql.users.findById(id);
}

検証:

  • エラー率に変化がないこと
  • レイテンシの p95 が 500ms 未満であること
  • ユーザーからの苦情がないこと

ロールバック: フィーチャーフラグをオフにする

フェーズ 5:MySQL への書き込みを停止(第 7 週)

目標: PostgreSQL をプライマリにする

手順:

  1. MySQL への書き込みを停止する
  2. MySQL を読み取り専用で稼働させ続ける
  3. 問題がないか監視する

コード:

async function createUser(data: CreateUserDto) {
  return postgres.users.create(data);
  // No longer writing to MySQL
}

検証:

  • すべての操作が正常に動作すること
  • MySQL が書き込みを受信していないこと

ロールバック: MySQL への書き込みを再び有効にする

フェーズ 6:廃止(第 8 週)

目標: MySQL を削除する

手順:

  1. MySQL のデータをアーカイブする
  2. MySQL クラスターをシャットダウンする
  3. MySQL クライアントコードを削除する

ロールバック: 不可(後戻りできない時点)

検証戦略

データ整合性チェック
def validate_migration():
    # Row counts
    mysql_count = mysql.query("SELECT COUNT(*) FROM users")[0]
    pg_count = postgres.query("SELECT COUNT(*) FROM users")[0]
    assert mysql_count == pg_count

    # Random sampling
    sample = mysql.query("SELECT * FROM users ORDER BY RAND() LIMIT 1000")
    for row in sample:
        pg_row = postgres.query("SELECT * FROM users WHERE id = %s", [row['id']])
        assert row == pg_row

    # Checksums
    mysql_checksum = mysql.query("SELECT MD5(GROUP_CONCAT(id, email)) FROM users")
    pg_checksum = postgres.query("SELECT MD5(STRING_AGG(id::text || email, '')) FROM users")
    assert mysql_checksum == pg_checksum

ロールバック計画

フェーズ 1~3 のロールバック(容易)
  • PostgreSQL への書き込みを無効にする
  • ユーザーへの影響なし
  • MySQL のデータは引き続き有効
フェーズ 4 のロールバック(中程度)
  • フィーチャーフラグを切り替える
  • 読み取り先を MySQL に戻す
  • ユーザーへの軽微な影響(数秒)
フェーズ 5 以降のロールバック(困難)
  • MySQL への書き込みを再び有効にする必要がある
  • データが失われる可能性がある(フェーズ 5 以降の書き込み)
  • デュアルライトの再開が必要

リスク軽減

リスク 1:データ損失

軽減策:

  • 検証が完了するまでデュアルライトを続ける
  • トランザクションログを取得する
  • 継続的にバックアップする
リスク 2:パフォーマンスの低下

軽減策:

  • PostgreSQL の負荷テストを行う
  • クエリを最適化する
  • コネクションプーリングを使用する
リスク 3:スキーマの違い

軽減策:

  • スキーマ検証スクリプトを用意する
  • ステージング環境で移行をテストする
  • データ型の違いを文書化する

コミュニケーション計画

ステークホルダーへの進捗共有
**Week 0:** Migration announced
**Week 2:** Phase 1 complete (dual writes)
**Week 4:** Backfill complete
**Week 6:** Traffic shifted to PostgreSQL
**Week 8:** Migration complete
ステータスダッシュボード
  • 現在のフェーズ
  • データ同期の状況(%)
  • 検証結果
  • エラー率

テスト計画

移行前のテスト
  1. 開発環境でテストする
  2. ステージング環境で移行を一通り実施する
  3. PostgreSQL の負荷テストを行う
  4. ロールバック手順を検証する
移行中
  1. 継続的に監視する
  2. 検証を自動化する
  3. 手動で抜き取りチェックを行う
  4. ユーザー受け入れテストを実施する

ベストプラクティス

  1. 小さなバッチ: 段階的に移行する
  2. デュアルライト: 両方のシステムの同期を維持する
  3. フィーチャーフラグ: 段階的な展開を制御する
  4. 継続的に検証する: 信頼するだけでなく、確認する
  5. ロールバックに備える: 最悪のケースに備えて計画する
  6. 注意深く監視する: メトリクスを追跡する
  7. こまめに共有する: ステークホルダーに常に情報を伝える

出力チェックリスト

  • 移行フェーズを定義する(5~7 フェーズ)
  • デュアルライトを実装する
  • バックフィルスクリプトを準備する
  • 検証戦略を策定する
  • フィーチャーフラグを設定する
  • フェーズごとのロールバック計画を立てる
  • リスク軽減策を策定する
  • コミュニケーション計画を立てる
  • 監視ダッシュボードを用意する
  • テストチェックリストを用意する

コメント