gh-ost は MySQL のオンラインスキーマ変更における強力なツールですが、銀の弾丸ではありません。本記事では、実運用で検証された制限とハマりどころを、現実のシナリオと例つきで簡潔にまとめます。いつ使い、いつ避けるかの判断材料に。
1. ハードブロッカー: これに該当するなら止める
gh-ost のいくつかの制限は譲れません。次のどれかに該当するなら、pt-online-schema-change のような代替を探すか、マイグレーション戦略を見直す必要があります。
外部キー (FK)
gh-ost は外部キー制約を持つテーブルをサポートしません。あなたのテーブルが他のテーブルから参照されている (「親」テーブル) 場合、gh-ost は実行を拒否します。これはデータ不整合を防ぐための重要な安全機能ですが、多くのアプリケーションにとって大きなブロッカーでもあります。
現実のシナリオ: customers テーブル (主キー id) と、customers.id を参照する外部キー customer_id を持つ orders テーブルがあるとします。gh-ost で customers を ALTER しようとすると、customers が親テーブルであるためマイグレーションは失敗します。この場合、外部キー制約を一時的に外すか、pt-online-schema-change のような別ツールを使うか、メンテナンス時間帯にマイグレーションを実行することを検討する必要があります。
トリガ
既にトリガを持つテーブルは gh-ost ではサポートされません。監査やロギングなどのために既存のトリガがある場合、gh-ost はマイグレーションを実行できません。
例: payments テーブルに監査用トリガがあるなら、監査ロジックをアプリケーション層に移すか、トリガを扱える別ツールを使う必要があります。
共有ユニークキーが無い
gh-ost は行を反復処理するために、ソースと ghost テーブルで同一の PRIMARY KEY または UNIQUE KEY を共有することを要求します。スキーマ変更がこのキーの変更や削除を含むなら、gh-ost は進められません。
例: 多カラムの主キーの構成を変える必要があるなら、マイグレーションを複数ステップに分けるか (例: 新しいユニークキーを追加し、データをバックフィルし、新しいキーへ切り替える)、別のマイグレーションツールを使う必要があります。
2. インフラ要件: スムーズなマイグレーションの必須事項
ハードブロッカーに加えて、gh-ost にはマイグレーション成功のために満たすべきインフラ要件があります。
バイナリログのフォーマットとイメージ
gh-ost は Row-Based Replication (RBR) が有効である必要があります。プライマリが Statement-Based Replication (SBR) なら、RBR を有効にしたレプリカを用意し、gh-ost をそこに接続することになります。さらに、多くのマネージドクラウド DB サービスでは binlog_row_image=FULL が必要です。
例 (クラウド環境):
gh-ost --assume-rbr --host=<replica_host> --cut-over=default ...権限
gh-ost はレプリケーション関連の特定権限を必要とし、場合によっては SUPER に近い能力を要求します。Amazon RDS や Azure Database for MySQL のようなマネージド DB 環境では取得が難しいことがあります。オンラインスキーママイグレーションツールに必要な権限については、必ずプラットフォームのドキュメントを確認してください。
3. 「オンライン」なのにロック: カットオーバーと長時間トランザクション
gh-ost は「オンライン」ツールですが、最後のカットオーバー段階では新旧テーブルの入れ替えにメタデータロック (MDL) が必要です。通常は短い一瞬ですが、対象テーブルへの長時間クエリがこの入れ替えをブロックすれば、軽い停止が重大インシデントに化けます。
現実のシナリオ: マイグレーション対象のテーブルに対して BI チームが 15 分の SELECT を流しているちょうどそのとき、あなたがカットオーバーしようとする。gh-ost は MDL を待ち、デプロイが固まり、他のアプリケーショントラフィックもブロックしかねません。これを避けるには、他チームと調整し、低トラフィック時間帯にカットオーバーを設定し、長時間クエリを止める段取りを用意します。
4. 性能と容量の落とし穴
gh-ost は性能の魔法の杖ではありません。理解しておくべき性能・容量の事情があります。
フルコピーのための余裕
gh-ost は ghost テーブルを作り、元テーブルのデータをすべてコピーします。フルコピーぶんの空き容量と、マイグレーション中に増えるバイナリログぶんの空き容量が必要です。
高書き込みレートで gh-ost が追い抜かれる
極端な書き込み負荷では、gh-ost のシングルスレッドな binlog 処理がボトルネックになります。適用すべき変更のバックログが処理速度より速く膨らみ、マイグレーションがどんどん遅れます。高書き込み負荷では pt-online-schema-change のほうが性能が出ることもあります。あなたのワークロードに合うかは、両方を実環境でテストして決めるのが鉄則です。
古いテーブルの削除
カットオーバー後、gh-ost は古いテーブルを削除します。非常に大きなテーブルでは I/O スパイクとレプリケーション遅延が起きます。低トラフィック時間帯に行うか、大きなテーブルの削除はより慎重なハウスキーピングプロセスで扱うのが安全です。
5. トポロジ互換性とネイティブ DDL
Galera/PXC 非対応
gh-ost はそのロックとテーブル入れ替え戦略のため、Galera や Percona XtraDB Cluster (PXC) と互換ではありません。これらの環境では、pt-online-schema-change のほうが一般に安全で推奨されます。
ネイティブ MySQL のほうが速いかもしれない
最近の MySQL (8.0+) では多くの DDL 操作が INSTANT や INPLACE で実行され、gh-ost のような外部ツール無しに、ほぼゼロインパクトで実行できます。複雑なツールに手を伸ばす前に、ネイティブ DDL で足りないかを必ず確認しましょう。
例: MySQL 8.0 では、データ型とデフォルト値次第で、デフォルト値付きカラム追加は INSTANT 操作になり得ます。この場合ネイティブ ALTER TABLE のほうが gh-ost よりはるかにシンプルで速くなります。
クイック判断チェックリスト
gh-ost があなたのマイグレーションに合うかを判断するためのチェックリスト:
- テーブルに FK やトリガがある? → gh-ost は使わない。 pt-online-schema-change を検討。
- ROW binlog と共有 UNIQUE/PRIMARY キーを用意できる? → OK。
- カットオーバーを調整できる (長時間クエリ無し)? → OK。
- Galera/PXC トポロジを使っている? → pt-online-schema-change を優先。
- MySQL 8.0+ か? → ネイティブ INSTANT/INPLACE DDL で済まないか確認。
すべてにチェックが入り、レプリカでマイグレーションを先にテスト済みなら、gh-ost は大規模かつホットなテーブルでのオンラインスキーマ変更の優れた選択肢です。本番への影響を最小限に抑えられます。