Skip to content

필사 모드: DB マイグレーションツール 2026 — Atlas / Flyway / Liquibase / Bytebase / pgroll / Squawk / gh-ost 徹底比較

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

プロローグ — 「マイグレーション一行で 5 分ダウン」

2026 年のあるチームのポストモーテム。

> 23:14、いつも通りのデプロイ。`ALTER TABLE orders ADD COLUMN status_v2 VARCHAR(32) NOT NULL DEFAULT 'pending'`。23:14:08、プライマリでロック取得。23:14:09、すべてのクエリがキューに溜まり始める。23:14:42、バックエンドの connection pool が枯渇、5xx が始まる。23:19:31、マイグレーション終了。23:19:34、キュー解消、復帰。**5 分 22 秒のダウン。** テーブルには 4 億行あった。

これは 2026 年でもよくある光景だ。ツールは十分すぎるほどある — Flyway、Liquibase、Atlas、Bytebase、pgroll、Squawk、gh-ost、pt-osc、Reshape、dbmate、golang-migrate、Diesel、Alembic、Prisma Migrate、Drizzle Kit。それでも **「どのマイグレーションが安全か」をツールが教えてくれなければ**、5 分ダウンは繰り返される。

この記事では 2026 年の DB マイグレーションツールの地図を描く。誰が何を得意で、誰が何を不得意とするか、そして自分のチームは何を選ぶべきかまで。

1 章 · 2026 年 DB マイグレーション地図 — 宣言型 vs 命令型 vs オンライン変更

まず全体像。**すべてのマイグレーションツールは三つの軸のどこに立つか**で分かれる。

軸 1: 宣言型 (declarative) vs 命令型 (imperative)

- **命令型**: `ALTER TABLE`、`CREATE INDEX` などの SQL スクリプトを人が書き、ツールは「どのスクリプトをどの順に実行したか」を追跡する。Flyway・Liquibase・dbmate・golang-migrate・Alembic・Sqitch・Diesel・Prisma Migrate (デフォルト)。

- **宣言型**: 人は「望ましいスキーマ状態」だけを書き、ツールが現状と比較して差分から ALTER 文を生成する。Atlas・Drizzle Kit・Prisma Migrate (prototype / db push)・Bytebase の GitOps モード。

宣言型は Terraform がインフラに対して行ったことを DB スキーマに対して行う。利点: スキーマがコードとして一望できる。欠点: 生成された ALTER が常に安全だとは限らない (rename を drop+add に分解してしまうなど)。

軸 2: オンライン (online) vs オフライン (offline)

- **オフライン**: マイグレーション中はテーブルがロックされる、またはクエリがブロックされる。多くの伝統的ツールのデフォルト。

- **オンライン**: ライブトラフィックが流れている間にスキーマを変更する。gh-ost・pt-osc・Reshape・pgroll。シャドウテーブル + トリガ/論理レプリケーションで少しずつコピーしてからカットオーバー。

小さなテーブル (数十万行以下) ならオフラインがシンプル。大きなテーブル (数億行・高トラフィック) ではオンラインが必須。

軸 3: forward-only vs reversible

- **reversible**: すべての up マイグレーションに対になる down が必要。Flyway・Alembic・golang-migrate が推奨。事故時にロールバック。

- **forward-only**: ロールバックは新しいマイグレーションを追加して行う。Sqitch と Atlas の推奨モード。理由: 「4 億行の INSERT を 5 分で本当に巻き戻せる down はほぼ存在しない — 幻想に近い」。

2026 年のシニアたちの共通認識: **forward-only + 短く安全な変更の連続** が reversible より現実的。down は「いま追加した空のカラムを drop する」程度までしか意味を持たない。

一枚要約

| ツール | モデル | オンライン? | 言語・対象 | 推奨用途 |

| --- | --- | --- | --- | --- |

| Atlas | 宣言型 | 直接は不可、統合あり | マルチ DB | 宣言型スキーマ + CI |

| Flyway 11 | 命令型 | 不可 | Java 親和 | エンタープライズ標準 |

| Liquibase 4.30 | 命令型 + メタ | 不可 | Java・XML/YAML | 大企業・マルチ DB |

| Sqitch | 命令型 + DAG | 不可 | DB 中立 | 依存性明示型 |

| Bytebase 3 | 両方 + ワークフロー | 統合あり | マルチ DB | DB DevOps・レビュー |

| Squawk | リンタ | n/a | Postgres | CI ゲート |

| pgroll | 宣言型 + expand/contract | 可 | Postgres | 無停止 Postgres |

| gh-ost | online change | 可 | MySQL | 大規模 MySQL |

| pt-osc | online change | 可 | MySQL | クラシック MySQL |

| Reshape | online change | 可 | Postgres | Rust・無停止 |

| dbmate | 命令型 | 不可 | マルチ DB・Go CLI | 軽量 CLI |

| golang-migrate | 命令型 | 不可 | Go・マルチ DB | Go 標準 |

| Diesel | 命令型 + ORM | 不可 | Rust | Rust 親和 |

| Alembic | 命令型 + 自動生成 | 不可 | Python・SQLAlchemy | Python 標準 |

| Prisma Migrate | 両方 | 不可 | TypeScript | Node 親和 |

| Drizzle Kit | 宣言型 + 命令型 | 不可 | TypeScript | TS・軽量 |

これが 2026 年の地図。ここから一マスずつ見ていく。

2 章 · Expand-Contract パターン + よくある落とし穴

ツールを選ぶ前に **パターン** を理解しておく必要がある。良いツールでも間違ったパターンで使えばロックする。

Expand-Contract (Parallel Change)

無停止マイグレーションの中核パターン。**三段階に分割する。**

1. **Expand**: 旧スキーマと新スキーマが共存するように追加だけする。drop はしない。

2. **Migrate**: コードが新スキーマで読み書きするようにする。バックフィルで過去データを新スキーマへコピー。

3. **Contract**: すべてのコードが新スキーマだけを使うと確認できたら、旧スキーマを drop。

例 — カラムの rename (`email` → `email_address`)。

- 単純な rename は危険: 旧カラムを使ってデプロイ中のコードが即座に壊れる。

- expand-contract: `email_address` カラムを NULL 許可で追加 → コードが両方を書き込む → バックフィルで旧データをコピー → コードが新カラムだけを読む → 旧カラムを drop。

pgroll・Reshape・gh-ost はこれを既定モデルとして自動化している。それ以外のツールでは人がマイグレーションを 3 つに分けないといけない。

よくある落とし穴 (foot-guns)

**1) NOT NULL を追加 (大きなテーブル)**

Postgres 11+ では `ALTER TABLE ... ADD COLUMN x INT NOT NULL DEFAULT 0` はメタデータだけ書き換える (速い)。しかし `ALTER TABLE ... ALTER COLUMN x SET NOT NULL` はテーブル全体をスキャンしながら ACCESS EXCLUSIVE ロック。4 億行なら分単位でロック。

- 安全: `ALTER TABLE ... ADD CONSTRAINT x_not_null CHECK (x IS NOT NULL) NOT VALID` → `VALIDATE CONSTRAINT x_not_null` → 次のデプロイで `SET NOT NULL`。NOT VALID はロックなし。

- MySQL: 同様のパターン + gh-ost / pt-osc。

**2) カラムの rename**

- 単純な `ALTER TABLE ... RENAME COLUMN` は普通メタデータだけだが、**デプロイ中のコードが旧名を参照していると即座に壊れる。**

- 安全: expand-contract。

**3) 型変更 (INT → BIGINT)**

- Postgres: 通常テーブル全体を書き直し (rewrite)。大きなテーブルは分単位のロック。

- 安全: 新カラムを BIGINT で追加 → バックフィル → コード切替 → 旧カラム drop。

**4) インデックス追加**

- Postgres: `CREATE INDEX CONCURRENTLY` はロックを取らない。マイグレーションツールがトランザクション内で実行すると失敗する — トランザクション外で実行が必要。

- MySQL: 小テーブルは即時。大テーブルは gh-ost / pt-osc。

**5) デフォルト値変更 (Postgres 11 未満 / 一部の型)**

- Postgres 11 未満: デフォルト追加でテーブル全体を書き直し。11+ ではメタデータのみ。

- 安全: 11+ にアップグレード。または default なしで追加してバックフィル。

**6) Foreign key 追加**

- ロックは短いが両方のテーブルに掛かる。ライブトラフィックが多いとタイムアウトリスク。

- 安全: `NOT VALID` で追加 → 別トランザクションで `VALIDATE CONSTRAINT`。

**7) 大きな DELETE / UPDATE**

- 一つのトランザクション内で数百万行を更新 = WAL 爆発、レプリカ lag、ロック保持。

- 安全: バッチ (例: 1 万行ずつ、sleep を挟む)。ツールはこれを直接やってくれない — 別のバックフィルジョブで。

要点: **マイグレーションツールは「スクリプトを順に走らせる何か」にすぎず、安全性を保証しない。** 安全性は上のパターン + (Squawk のような) リンタ + レビューから生まれる。

3 章 · Atlas (Ariga) — 宣言型スキーマ管理の代表

Atlas (atlasgo.io) は 2022 年に始まり、2024-2025 年にシェアを急速に伸ばした。**HashiCorp の Terraform を DB スキーマに対して行うツール。**

モデル

`schema.hcl` (または SQL / JSON) に望ましいスキーマを書く。Atlas が現在の DB と比較して差分を計算し ALTER 文を生成する。

schema "public" {}

table "users" {

schema = schema.public

column "id" {

type = bigint

null = false

}

column "email" {

type = varchar(255)

null = false

}

primary_key { columns = [column.id] }

index "idx_users_email" {

columns = [column.email]

unique = true

}

}

CLI は二つのモードを持つ。

- **Declarative**: `atlas schema apply --to file://schema.hcl --url $DB_URL` — 差分を計算して即適用。

- **Versioned**: `atlas migrate diff add_user_email` — 差分を SQL ファイルとして書き出し、後で `atlas migrate apply` で適用。プロダクションではこちら推奨。

強み

- **DB 中立**: Postgres・MySQL・SQLite・SQL Server・MariaDB・ClickHouse・MS SQL・Redshift など。

- **CI 統合**: `atlas migrate lint` で危険な変更 (NOT NULL 追加・DROP COLUMN・インデックス欠落) を自動検出。GitHub Actions・GitLab CI 連携。

- **ORM 統合**: GORM・Ent・Hibernate・Prisma・Sequelize からスキーマを抽出して Atlas で管理。

- **スキーマ可視化**: `atlas schema inspect` + `atlas schema fmt` + ERD 生成。

弱み

- 宣言型モデルは **カラム rename を drop+add で処理しがち**。Atlas は `--diff-policy` ヒントで抑えられるが自動ではない。

- 無停止 (expand-contract) は直接サポートされていない — versioned モードで人が分割する必要がある。

- 無料版と有料 (Atlas Cloud, Pro) の機能差が大きい: 一部の lint・スキーマ監視・マルチテナントは Pro 専用。

推奨用途

- 新規 Go バックエンド。

- Terraform などの IaC に慣れたチーム。

- マルチ DB 環境を単一ツールで統一したいとき。

2026 年時点で Atlas は **宣言型陣営の事実上の標準**。

4 章 · Flyway 11 — Java 陣営のクラシック

Flyway は 2010 年から、JBoss / Spring Boot エコシステムの標準。2024 年に Redgate が買収、11.x はモジュール整理と新規データベースアダプタが中心。

モデル

`V{version}__{description}.sql` 命名規約。素直な命令型。

db/migration/

V1__create_users.sql

V2__add_email_index.sql

V3__add_orders.sql

R__create_view_active_users.sql # Repeatable

U2__rollback_email_index.sql # Undo (Teams)

DB の `flyway_schema_history` テーブルがどの V を実行済みかを追跡。`flyway migrate` で未適用分のみを順に適用。

強み

- **シンプル**: SQL を知っていれば終わり。新メンバーが 30 分で理解。

- **Spring Boot オートコンフィグ**: 一行 — `spring-boot-starter-flyway`。

- **DB カバレッジが広い**: Postgres・MySQL・Oracle・SQL Server・DB2・Sybase・MongoDB (Pro)・Snowflake・BigQuery など 50+。

- **コールバックフック**: `beforeMigrate`・`afterMigrate`・`beforeEachMigrate` などのライフサイクルフック。

- **baseline**: 既存 DB に後から Flyway を導入する際の baseline マーキング。

弱み

- **ロールバックは有料 (Teams / Enterprise)**: OSS は forward-only。`Undo` マイグレーションは Teams 専用。

- **オンラインスキーマ変更は非対応**: 大テーブルは gh-ost / pt-osc / pgroll との併用が必要。

- **宣言型モードなし**: 11.x で一部 (Auto-generate) は入ったが、Atlas / Drizzle 水準ではない。

- **Lint は弱い**: 危険パターンの自動検出は Squawk のような外部ツールに委ねる。

推奨用途

- Spring Boot / Java / Kotlin バックエンド。

- Oracle・DB2 などのエンタープライズ DB。

- 「SQL をそのまま見たい、抽象化は少なめがよい」チーム。

2026 年でも **JVM 陣営のデフォルト**。ただし新規プロジェクトが Flyway だけを使うケースは減り、Atlas / Squawk と組み合わせる例が増えた。

5 章 · Liquibase 4.30 — XML / YAML 親和

Liquibase は Flyway のライバル。2006 年から、4.30 (2025-2026) は changelog フォーマット・DB サポート・UX 改善が中心。

モデル

`changelog` ファイルに changeSet を列挙する。フォーマットは XML・YAML・JSON・SQL のいずれも可能。

databaseChangeLog:

- changeSet:

id: 1

author: alice

changes:

- createTable:

tableName: users

columns:

- column:

name: id

type: BIGINT

autoIncrement: true

constraints: { primaryKey: true, nullable: false }

- column:

name: email

type: VARCHAR(255)

constraints: { nullable: false, unique: true }

rollback:

- dropTable: { tableName: users }

強み

- **強い DB 抽象化**: 同じ changeSet が Postgres・MySQL・Oracle それぞれに適切な SQL に変換される。クロス DB プロジェクトで有利。

- **OSS でロールバックが一級**: 各 change に明示的なロールバックを定義可能。

- **ポリシーチェック** (Pro): 危険パターンの自動ブロック。

- **GUI ツール** (Liquibase Hub、DBeaver 統合)。

- **多数の change タイプ**: `addColumn`・`createIndex`・`addForeignKey`・`mergeColumns` など 30+ の抽象 change。

弱み

- **XML / YAML の冗長さ**: SQL 1 行が YAML 10 行になる。

- **抽象化のコスト**: 抽象 change が生成する SQL は必ずしも最適ではない。大テーブルでは結局 raw SQL に落とす。

- **宣言型は弱い**: Liquibase は命令型。宣言型が欲しければ別途。

- **OSS と Pro の機能差が大きい**: ポリシーチェック・ロールバックの一部機能・Hub は Pro。

Flyway vs Liquibase 一行で

- Flyway: SQL が好きなら。

- Liquibase: クロス DB・抽象化・明示的ロールバックが必要なら。

2026 年時点で二者はほぼ拮抗、ただし新規プロジェクトは Atlas に移る流れが明確。

6 章 · Sqitch — 依存性ベースの旧学派

Sqitch (sqitch.org) は 2012 年に David Wheeler が作った「Git のようなマイグレーションツール」。**バージョン番号ではなく依存グラフ** でマイグレーションを追跡する。

モデル

各変更には名前がある。`sqitch add appchanges` で 3 つのファイルが生成される。

deploy/appchanges.sql -- 適用 SQL

revert/appchanges.sql -- 巻き戻し SQL

verify/appchanges.sql -- 検証 SELECT

`sqitch.plan` に依存性を明示する。

add_users 2026-05-16T12:00:00Z alice

add_orders [add_users] 2026-05-16T13:00:00Z alice -- add_users に依存

`sqitch deploy` は依存性を満たす順序で適用。`sqitch verify` は verify SQL を実行して本当に適用されたかを確認する。

強み

- **依存性の明示**: マイグレーションが 100 を超えると依存グラフが真価を発揮。

- **verify が一級**: 「マイグレーションが適用された」と「実際に動作する」を区別。

- **DB 中立**: Postgres・MySQL・Oracle・SQLite・Snowflake・Firebird・Vertica・Exasol。

- **VCS 親和**: ブランチ間のマイグレーション競合が少ない (依存性ベースなので)。

弱み

- **学習コスト**: コマンドが多く (`deploy`・`revert`・`verify`・`bundle`・`tag`・`rework`)、他ツールとは異なるメンタルモデル。

- **コミュニティが小さい**: GitHub stars・StackOverflow の回答数が Flyway / Liquibase の 1/10 程度。

- **CI 統合・GUI は弱い**: すべて CLI。

- **Perl 依存**: 他ツールよりインストールが面倒 (Docker で回避可能)。

推奨用途

- マイグレーションが 1000 を超えるモノリス DB。

- 「バージョン番号衝突」が頻発するマルチブランチ環境。

- 依存グラフ + verify モデルが好きなチーム。

2026 年の Sqitch は **ニッチだが忠誠度の高い** ツール。PostgreSQL のコアコントリビュータの一部は今も愛用。

7 章 · Bytebase 3 — DB DevOps + レビュー

Bytebase (bytebase.com) は 2021 年スタート、2025 年に 3.x へジャンプ。コンセプトは **「DB 向けの GitLab / GitHub」**。

モデル

Web UI + GitOps。マイグレーション SQL を PR として上げると Bytebase が:

1. **自動 lint** (SQL Review、Squawk スタイルのルールセット)。

2. **承認ワークフロー** (DBA がレビュー)。

3. **ステージ別自動デプロイ** (dev → staging → prod)。

4. **スキーマドリフト検出** (Bytebase が知らない変更が prod に入ったらアラート)。

5. **データマスキング・アクセスコントロール** (誰がどのカラムを見られるか)。

強み

- **人間ワークフローが一級**: 他ツールは CLI / CI で止まるところ、Bytebase は人がレビューする UI がメイン。

- **マルチ DB・マルチ環境**: 50+ DB サポート、dev/staging/prod ライフサイクル。

- **スキーマエディタ (GUI)**: 非開発者もマイグレーション提案が可能。

- **データマスキング**: PII カラムを開発者から隠す。

- **セルフホスト OSS**: セルフホストは無料 (一部機能はライセンスでゲート)。

弱み

- **インフラコスト**: Bytebase 自身がサーバ + DB。小さなチームには過剰。

- **ベンダーロックイン**: GitOps モードを使うと他ツールへの移行が難しい。

- **実マイグレーションは別ツールに委譲**: Bytebase 自身は ALTER を実行せず、gh-ost / pt-osc / Flyway / Liquibase を呼ぶ。オーケストレータに近い。

推奨用途

- DBA チームがあり、開発者が直接 prod DB を触ってはいけない環境。

- 50+ DB インスタンスを運用する大組織。

- 「PR + 承認」ワークフローを DB にも適用したいチーム。

2026 年の Bytebase は **DB DevOps の事実上の先頭**。PlanetScale / Neon などのサーバレス DB が自前 UI を作って競合してきているが、on-prem / マルチクラウドは Bytebase 優位。

8 章 · Squawk — Postgres マイグレーションリンタ

Squawk (squawkhq.com) は Steve Dignam が 2020 年に作った小さな OSS。**マイグレーション SQL を読んで危険なパターンを検出する。** マイグレーションツールではなくリンタ。

モデル

squawk migration.sql

危険なパターンを見つけるとエラー/警告。

migration.sql:1:1: warning: adding-not-nullable-field

ALTER TABLE "user" ADD COLUMN "email" TEXT NOT NULL

Adding a NOT NULL field requires a table rewrite ...

Use ADD COLUMN ... DEFAULT NULL, backfill, then ALTER ... SET NOT NULL.

検出ルール (Postgres 中心、30+)

- `adding-not-nullable-field` — NOT NULL 追加 → ロック。

- `changing-column-type` — 型変更 → 書き直し。

- `disallowed-unique-constraint` — UNIQUE 制約追加 → 全スキャン・ロック。

- `prefer-text-field` — VARCHAR(n) でなく TEXT。

- `require-concurrent-index-creation` — `CREATE INDEX` (CONCURRENTLY なし) → ロック。

- `transaction-nesting` — トランザクション内で `CREATE INDEX CONCURRENTLY` → 失敗。

- `renaming-column` — rename は既存コードを即座に壊す。

- `renaming-table` — 上と同じ。

- `ban-drop-column` — DROP COLUMN は expand-contract で。

- `constraint-missing-not-valid` — `ADD CONSTRAINT` (NOT VALID なし) → 全スキャン。

強み

- **CI に一行**: `squawk **/V*.sql` — すべてのマイグレーションに自動ゲート。

- **高速**: Rust 製、ファイルあたり ms 単位。

- **GitHub Actions コメント**: PR にコメントで危険を通知。

- **マイグレーションツール中立**: Flyway・Liquibase・Atlas・dbmate などどのツールの SQL でも lint 可能。

弱み

- **Postgres 専用**: MySQL のルールはほぼなし。

- **偽陽性**: 「このテーブルは小さいから NOT NULL OK」を知らない。ルールごと disable で回避。

- **データ安全性は見ない**: ロックは見るが「このカラム drop が本当に未使用か」までは見ない。

推奨用途

- Postgres を使うすべてのチームの CI に追加 (無料、1 行)。

- 大テーブルがある環境ではほぼ必須。

2026 年のシニア共通認識: **Postgres を使うなら Squawk はデフォルト。** ツール選択と無関係に CI に入れる。

9 章 · pgroll (Xata) — 無停止 Postgres マイグレーション

pgroll (github.com/xataio/pgroll) は Xata が 2023-2024 年に OSS として公開。野心は **「expand-contract をツール自身が自動化する」**。

モデル

JSON でマイグレーションを定義する。pgroll が自動的に view + トリガを作って、旧バージョンと新バージョンのスキーマを同時に露出する。

{

"name": "rename_email_column",

"operations": [

{

"rename_column": {

"table": "users",

"column": "email",

"to": "email_address"

}

}

]

}

`pgroll start` で開始 → 二つのバージョンが共存 (view で露出) → `pgroll complete` で旧カラム削除。途中で `pgroll rollback` も可能。

動作原理

1. `pgroll start` が新カラム/テーブル/インデックスを追加 + view を生成。

2. 旧 view = 旧スキーマ、新 view = 新スキーマ。コードは `SET search_path` でどちらの view を使うか選ぶ。

3. トリガが双方向にデータを同期 (旧カラムへの書き込みは新カラムにも、新カラムへの書き込みは旧カラムにも)。

4. バックフィルがバックグラウンドで旧データを新カラムにコピー。

5. すべてのトラフィックが新 view に移ったら `pgroll complete` で旧カラム drop。

強み

- **本当に無停止**: トラフィックが流れている間にカラム rename・型変更・NOT NULL 追加が可能。

- **安全なロールバック**: カットオーバー前は旧 view が生きているので即座に復帰。

- **宣言型 + expand-contract**: 人が 3 つのマイグレーションを分ける必要なし。

- **Postgres 14+ ネイティブ**: トリガ・view・論理デコーディングを活用。外部依存なし。

弱み

- **Postgres 専用**。

- **トリガオーバーヘッド**: 双方向同期トリガが書き込み負荷を増やす。

- **使用人口がまだ少ない**: 2026 年でもプロダクション事例はトス・Notion・Xata 程度。事例の蓄積が必要。

- **すべての変更をサポートしてはいない**: パーティション・複雑な制約はまだ。

推奨用途

- Postgres 上で本当に無停止が必要なサービス (24/7 決済・メッセージング)。

- カラム rename・型変更が頻繁な高速進化スキーマ。

2026 年の pgroll は **Postgres 無停止マイグレーションの best bet**。ただし安定性は gh-ost (MySQL) にはまだ及ばない。

10 章 · gh-ost / pt-online-schema-change / Reshape — オンラインスキーマ変更

大テーブル + ライブトラフィック = オンラインスキーマ変更が必要。三つのツール。

gh-ost (GitHub、MySQL)

GitHub が 2016 年に作って OSS 化。**トリガなし、binlog ベース。**

動作:

1. シャドウテーブルを新スキーマで作成。

2. 旧テーブルの行を chunk 単位でシャドウに INSERT。

3. binlog を読んで進行中の変更 (INSERT / UPDATE / DELETE) をシャドウにも適用。

4. カットオーバー: 短いロックで旧テーブル ↔ シャドウを atomic に swap。

gh-ost \

--user="root" --password="..." \

--host=primary.db \

--database="app" --table="orders" \

--alter="ADD COLUMN status_v2 VARCHAR(32) NOT NULL DEFAULT 'pending'" \

--execute

- 強み: トリガなし → 旧テーブルへの負荷が少ない。throttle (レプリカ lag を見て自動減速) が優秀。インタラクティブ (CLI で実行中に一時停止・キャンセル)。

- 弱み: MySQL / MariaDB 専用。binlog 読み取り権限必須。外部キーがあるテーブルは扱いが難しい。

pt-online-schema-change (Percona、MySQL)

Percona Toolkit の一部。**トリガベース。**

動作:

1. シャドウテーブル + 旧テーブルに INSERT / UPDATE / DELETE トリガを設置。

2. chunk 単位で旧 → シャドウへコピー。

3. カットオーバー: 二回の RENAME TABLE で swap。

- 強み: 古くて安定。gh-ost が扱えない一部のケース (主に外部キー) に対応。

- 弱み: トリガが旧テーブルの書き込み負荷を増やす。throttle は gh-ost より弱い。

Reshape (Postgres、Rust)

2022 年に Fabian Lindfors が作った Rust 製ツール。**Postgres 向け expand-contract。**

動作: pgroll と似ている。SQL ではなく TOML でマイグレーションを定義 + view + トリガで旧/新を共存。

[[actions]]

type = "add_column"

table = "users"

column = "email_address"

data_type = "text"

nullable = true

- 強み: Rust で高速、API がきれい。

- 弱み: 2024 年からメンテナの活動が減ったとの評。2026 年のプロダクション利用は少ない。pgroll が事実上追い越した。

三者比較

| | gh-ost | pt-osc | Reshape | pgroll |

| --- | --- | --- | --- | --- |

| DB | MySQL | MySQL | Postgres | Postgres |

| トリガ | なし | あり | あり | あり |

| binlog | あり | なし | なし | なし |

| 活動度 (2026) | 中 | 低 | 低 | 高 |

| 推奨 | 大規模 MySQL | gh-ost が無理なケース | (回避) | Postgres |

2026 年の合意: **MySQL は gh-ost がデフォルト**、フォールバックが pt-osc。**Postgres は pgroll** が新興標準。

11 章 · dbmate / golang-migrate / Diesel / Alembic — 言語別オプション

各言語陣営のデフォルト。

dbmate (Go、マルチ DB)

amacneil/dbmate。一ファイルの Go バイナリ、CLI デザインがきれい。

dbmate new add_users

db/migrations/20260516120000_add_users.sql が生成される

ファイルは up / down 二セクション。

-- migrate:up

CREATE TABLE users (id BIGINT PRIMARY KEY, email TEXT NOT NULL);

-- migrate:down

DROP TABLE users;

- 強み: Postgres・MySQL・SQLite・ClickHouse・BigQuery 対応。依存ゼロ。シェル親和。Docker 親和。

- 弱み: 機能が少ない (lint・スキーマドリフト・ロールバックワークフローはない)。そのシンプルさが魅力。

golang-migrate (Go、マルチ DB)

`golang-migrate/migrate`。CLI + Go ライブラリ。

migrations/

000001_create_users.up.sql

000001_create_users.down.sql

- 強み: Go コードからライブラリとして直接呼べる。CockroachDB・Spanner・MongoDB アダプタ。

- 弱み: GitHub stars は多いがメンテナの帯域が減ったとの評。issue が積みあがり中。一部アダプタは maintenance のみ。

dbmate vs golang-migrate — 2024-2025 年に dbmate に移行したチームが増えた。**新規 Go プロジェクトは dbmate がデフォルト** (または Atlas)。

Diesel migrations (Rust)

Diesel ORM の一部。`diesel migration generate add_users` で `up.sql` / `down.sql` が生成される。

- 強み: Diesel と統合 — schema.rs を自動生成、コンパイル時型チェック。

- 弱み: Diesel 自身が重い ORM。SQLx / sqlx::migrate を好むチームも多い。

Alembic (Python、SQLAlchemy)

SQLAlchemy のマイグレーションツール。マイグレーションを Python コードで定義。

def upgrade():

op.add_column('users', sa.Column('email', sa.String(255), nullable=False))

def downgrade():

op.drop_column('users', 'email')

- 強み: SQLAlchemy モデルから **autogenerate** — モデルを変えると差分を自動でマイグレーションに生成。Python コードなので条件分岐 (`if dialect == 'postgresql':`) が可能。

- 弱み: autogenerate がカラム rename を drop+add と誤認。Python 依存が重い。SQLAlchemy を使わないと合わない。

2026 年でも **Python / Django は Django migrations**、**Python / FastAPI / SQLAlchemy は Alembic** がデフォルト。

12 章 · Prisma Migrate / Drizzle Kit — TypeScript 陣営

Node / TypeScript は分裂状態。二強。

Prisma Migrate

Prisma ORM の一部。`schema.prisma` にモデルを書き、`prisma migrate dev` でマイグレーション生成/適用。

model User {

id BigInt @id @default(autoincrement())

email String @unique

}

- 強み: スキーマ → マイグレーション → クライアント型を一気通貫。DX は圧倒的。

- 弱み: 重い Rust エンジン。raw SQL の制御が弱い。大テーブルでの安全マイグレーション生成を保証しない (rename を drop+add に)。pgbouncer transaction モードと衝突。

Drizzle Kit

Drizzle ORM の一部。コード (TypeScript) でスキーマ定義 → `drizzle-kit generate` で SQL 差分を生成。

export const users = pgTable("users", {

id: bigserial("id").primaryKey(),

email: varchar("email", { length: 255 }).notNull().unique(),

});

- 強み: 軽い (ランタイム依存が小さい)。raw SQL に近い — 生成 SQL を人が読んで修正。エッジランタイム (Cloudflare Workers) で OK。

- 弱み: 2026 年でもエコシステムは Prisma より小さい。一部の高度機能 (relations、complex types) は Prisma が強い。

2026 年の TS 合意:

- **DX 最優先、フルスタック Node** → Prisma。

- **エッジ・サーバレス・raw SQL 制御** → Drizzle。

- **大規模・無停止** → 両方とも不足、別途マイグレーションツール (Atlas / pgroll / gh-ost) と併用。

13 章 · 誰が何を選ぶべきか — ディシジョンツリー

| 状況 | 推奨 |

| --- | --- |

| 単一アプリ、Postgres、トラフィック少 | dbmate または golang-migrate + Squawk |

| 単一アプリ、MySQL、トラフィック少 | Flyway または dbmate |

| Java / Spring Boot | Flyway (または Liquibase) + Squawk |

| Node / TypeScript、フルスタック | Prisma + 規模到達時に Atlas |

| Node / TypeScript、エッジ | Drizzle Kit + Squawk |

| Python / Django | Django migrations |

| Python / FastAPI | Alembic |

| Rust | Diesel または SQLx + dbmate |

| Go、新規プロジェクト | Atlas (宣言型) または dbmate (シンプル) |

| マイクロサービス 50+ | Bytebase + 各サービスが選んだツール |

| 大規模 Postgres、無停止必須 | pgroll + Squawk + Atlas |

| 大規模 MySQL、無停止必須 | gh-ost + Flyway + Squawk-MySQL 代替 |

| DBA チームあり、レビューワークフロー | Bytebase 中心 |

| クロス DB (Postgres + MySQL + Oracle) | Liquibase または Bytebase |

| 累積マイグレーション 1000+ | Sqitch (依存グラフ) |

よくあるアンチパターン

- **「Prisma Migrate 一本で prod まで全部解決」**: 小テーブルなら OK、大テーブルに入るとロックで死ぬ。Squawk をゲートに。

- **「Liquibase の abstract change がうまくやってくれる」**: クロス DB ではしばしば suboptimal な SQL を生成。raw SQL に落として確認。

- **「down マイグレーションは常に書く」**: 4 億行 INSERT の down が本当に 5 分で回ると信じている? forward-only が現実的。

- **「マイグレーションツールが安全を保証」**: どのツールも NOT NULL を安全に追加してくれない。expand-contract + lint + レビューが安全。

- **「gh-ost を一回回せば必ず無停止」**: throttle 設定を間違えるとレプリカ lag 爆発。カットオーバー直前のロックが 5 秒を超えたら失敗。

14 章 · 韓国 / 日本の事例 — トス / カカオ / メルカリ

トス (Toss)

トスは 2023 年のカンファレンス (SLASH) で **gh-ost を MySQL で広範に使う** ことを公開。決済ドメインは 24/7 なのでロックは即売上損失。gh-ost で chunk サイズ・throttle をドメインごとにチューニング。

2025-2026 年のトスでは一部新規 Postgres サービスで pgroll を検討中との発表あり。Squawk はすべての新規マイグレーション PR の必須 CI ステップ。

カカオ (Kakao)

カカオはメッセンジャー・ペイ・バンクそれぞれ DB 戦略が違う。**カカオバンクは Oracle ベースで Liquibase + 独自ワークフロー**。カカオペイの一部新規サービスは Flyway + gh-ost (MySQL) の組み合わせ。カカオメッセンジャーは独自分散ストレージなので一般マイグレーションツールの範囲外。

2024 年にカカオの一部チームが Atlas を導入して Go バックエンドを統一したとの話がカンファレンスで出た。

メルカリ (Mercari、日本)

メルカリはマイクロサービス 100+ 環境。**各サービスがツール選択は自由**、ただし lint (Squawk・独自ルール) は共通 CI。Spanner を使うサービスが多いので Spanner CLI + 独自マイグレーションフレームワーク。

メルカリエンジニアリングブログでは「**Schema migration as code**」コンセプトをよく言及 — Atlas / Bytebase に似た宣言型モデルを社内で実装。

LY Corporation (LINE + Yahoo Japan)

2023 年合併後、LINE コアバックエンドの DB マイグレーションは Flyway 中心に標準化中。一部新規 Go サービスは Atlas。**Squawk-MySQL の代替として独自ルールを追加した sql-lint ツール** を社内で運用。

共通パターン:

- 大テーブルには必ず gh-ost (MySQL) / pgroll (Postgres)。

- CI に lint ゲートはデフォルト。

- DBA レビューが prod デプロイのゲート (Bytebase でも自前ツールでも)。

これが 2026 年の韓国・日本ビッグテックの流れ。

結論 — ツールは多く、パターンは少ない

長い記事を一ページに:

1. **ツールは十分にある。** Atlas、Flyway、Liquibase、Sqitch、Bytebase、pgroll、Squawk、gh-ost、pt-osc、Reshape、dbmate、golang-migrate、Diesel、Alembic、Prisma、Drizzle。新しく作る必要はない。

2. **選択は言語・チーム親和度から始める。** Java なら Flyway、Python なら Alembic、Go なら Atlas / dbmate、TS なら Prisma / Drizzle。

3. **無停止が必要ならパターンがツールを決める**。expand-contract → pgroll (Postgres) / gh-ost (MySQL)。

4. **Squawk (または同等リンタ) はデフォルト**。Postgres を使う限り CI に必ず入れる。

5. **ポジティブな down は幻想。** forward-only + 短く安全な変更の連続が reversible より現実的。

6. **マイグレーションツールは安全を保証しない。** expand-contract パターン + lint + レビューが安全。

最後に: **5 分ダウン** の原因はツールではなかった。`ALTER COLUMN ... SET NOT NULL` を 4 億行テーブルに一つのトランザクションで回したパターンが原因。ツールはそのまま、パターンを expand-contract に変えていれば 5 分は 0 秒になっていた。

参考 / References

- Atlas: https://atlasgo.io/

- Atlas GitHub: https://github.com/ariga/atlas

- Atlas migrate lint: https://atlasgo.io/versioned/lint

- Flyway: https://flywaydb.org/

- Flyway 11 release notes: https://documentation.red-gate.com/fd/release-notes-for-flyway-engine

- Liquibase: https://www.liquibase.com/

- Liquibase 4.30 docs: https://docs.liquibase.com/

- Sqitch: https://sqitch.org/

- Sqitch tutorial: https://sqitch.org/docs/manual/sqitchtutorial-pg/

- Bytebase: https://www.bytebase.com/

- Bytebase docs: https://www.bytebase.com/docs/

- Bytebase GitHub: https://github.com/bytebase/bytebase

- Squawk: https://squawkhq.com/

- Squawk GitHub: https://github.com/sbdchd/squawk

- pgroll: https://github.com/xataio/pgroll

- pgroll docs: https://pgroll.com/docs

- gh-ost: https://github.com/github/gh-ost

- gh-ost cheatsheet: https://github.com/github/gh-ost/blob/master/doc/cheatsheet.md

- pt-online-schema-change: https://docs.percona.com/percona-toolkit/pt-online-schema-change.html

- Reshape: https://github.com/fabianlindfors/reshape

- dbmate: https://github.com/amacneil/dbmate

- golang-migrate: https://github.com/golang-migrate/migrate

- Diesel migrations: https://diesel.rs/guides/getting-started

- Alembic: https://alembic.sqlalchemy.org/

- Prisma Migrate: https://www.prisma.io/docs/concepts/components/prisma-migrate

- Drizzle Kit: https://orm.drizzle.team/kit-docs/overview

- GitHub Engineering — gh-ost: https://github.blog/2016-08-01-gh-ost-github-s-online-migration-tool-for-mysql/

- PlanetScale schema changes: https://planetscale.com/docs/concepts/branching

- Toss SLASH talks: https://toss.tech/slash

- Mercari Engineering blog: https://engineering.mercari.com/en/blog/

- Strong Migrations (Rails コンテキスト): https://github.com/ankane/strong_migrations

- Expand and Contract pattern (Martin Fowler): https://martinfowler.com/bliki/ParallelChange.html

현재 단락 (1/411)

2026 年のあるチームのポストモーテム。

작성 글자: 0원문 글자: 20,183작성 단락: 0/411