- Published on
DB マイグレーションツール 2026 — Atlas / Flyway / Liquibase / Bytebase / pgroll / Squawk / gh-ost 徹底比較
- Authors

- Name
- Youngju Kim
- @fjvbn20031
プロローグ — 「マイグレーション一行で 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)
無停止マイグレーションの中核パターン。三段階に分割する。
- Expand: 旧スキーマと新スキーマが共存するように追加だけする。drop はしない。
- Migrate: コードが新スキーマで読み書きするようにする。バックフィルで過去データを新スキーマへコピー。
- 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 が:
- 自動 lint (SQL Review、Squawk スタイルのルールセット)。
- 承認ワークフロー (DBA がレビュー)。
- ステージ別自動デプロイ (dev → staging → prod)。
- スキーマドリフト検出 (Bytebase が知らない変更が prod に入ったらアラート)。
- データマスキング・アクセスコントロール (誰がどのカラムを見られるか)。
強み
- 人間ワークフローが一級: 他ツールは 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 も可能。
動作原理
pgroll startが新カラム/テーブル/インデックスを追加 + view を生成。- 旧 view = 旧スキーマ、新 view = 新スキーマ。コードは
SET search_pathでどちらの view を使うか選ぶ。 - トリガが双方向にデータを同期 (旧カラムへの書き込みは新カラムにも、新カラムへの書き込みは旧カラムにも)。
- バックフィルがバックグラウンドで旧データを新カラムにコピー。
- すべてのトラフィックが新 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 ベース。
動作:
- シャドウテーブルを新スキーマで作成。
- 旧テーブルの行を chunk 単位でシャドウに INSERT。
- binlog を読んで進行中の変更 (INSERT / UPDATE / DELETE) をシャドウにも適用。
- カットオーバー: 短いロックで旧テーブル ↔ シャドウを 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 の一部。トリガベース。
動作:
- シャドウテーブル + 旧テーブルに INSERT / UPDATE / DELETE トリガを設置。
- chunk 単位で旧 → シャドウへコピー。
- カットオーバー: 二回の 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 年の韓国・日本ビッグテックの流れ。
結論 — ツールは多く、パターンは少ない
長い記事を一ページに:
- ツールは十分にある。 Atlas、Flyway、Liquibase、Sqitch、Bytebase、pgroll、Squawk、gh-ost、pt-osc、Reshape、dbmate、golang-migrate、Diesel、Alembic、Prisma、Drizzle。新しく作る必要はない。
- 選択は言語・チーム親和度から始める。 Java なら Flyway、Python なら Alembic、Go なら Atlas / dbmate、TS なら Prisma / Drizzle。
- 無停止が必要ならパターンがツールを決める。expand-contract → pgroll (Postgres) / gh-ost (MySQL)。
- Squawk (または同等リンタ) はデフォルト。Postgres を使う限り CI に必ず入れる。
- ポジティブな down は幻想。 forward-only + 短く安全な変更の連続が reversible より現実的。
- マイグレーションツールは安全を保証しない。 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