オンラインDDLは、現代のデータベースにおいて重要な機能であり、MySQLの近代化戦略の中核を成すものです。オンラインDDLを利用することで、データベースの運用を妨げるような大きなダウンタイムやロックを伴うことなく、スキーマ変更を行うことができます。これは、データベースが読み取りおよび書き込みの両方を継続して受け付けたまま、DDL操作が実行されることを意味しており、ダウンタイムを最小限に抑えつつ、進行中の処理への影響を回避することが可能になります。
オンラインDDLは、高可用性が求められ、メンテナンスウィンドウを確保することが難しい、あるいは確保できても業務への影響が大きいアプリケーションにおいて、特に重要です。この機能は、ユーザー体験やサービスの可用性に影響を与えることなく、スケールや進化、スキーマ変更を行う必要がある大規模な運用データベースにとって不可欠なものです。
本ブログでは、まずオンラインDDLとは何かを解説し、その後、分散SQLデータベースであるTiDBがオンラインDDL操作をどのように効率的に処理しているのかを詳しく見ていきます。
オンラインDDLとは何か、そしてなぜ現代のMySQLシステムにとって重要なのか
オンラインDDLとは、データベースを読み取り・書き込み可能な状態のまま、カラムの追加、インデックスの作成・削除、制約の変更といったスキーマ変更を行う機能です。テーブルをブロックする代わりに、システムは実際のトラフィックと並行して変更処理を実行します。これにより、稼働時間を維持し、p95 / p99レイテンシを保護するとともに、クエリやアプリケーションを停止させてしまう長時間のメタデータロックを回避することで、オンラインDDLの性能を向上させます。
Google F1 のアプローチを踏襲し、オンラインDDLは安全な遷移ステージ (例:準備 → バックフィル/検証 → 公開) に分割されています。これにより、スキーマ変更の進行中も読み取り・書き込みを継続することができます。データのバックフィルはレート制限をかけたうえでバックグラウンドで実行され、新しい構造 (「シャドー」インデックスなど) は既存の構造と並行して構築されます。そして、メタデータの切り替えは最後にアトミックに行われるため、各ノードは最大でも1つ前のDDLバージョンまでの遅れにとどまり、データ破損や障害が発生することはありません。その結果、本番環境の負荷がかかった大規模テーブルであっても、スキーマ進化の過程において予測可能なパフォーマンスが実現されます。特に、バックフィルを安全に並列化・スロットリングするTiDBのDDL最適化により、その効果はさらに高まります。
ロック型からノンブロッキングへ:DDL操作の進化
- ノンブロッキングな操作:テーブルに対する長時間のロックを回避します。
- 最小限のダウンタイム:スキーマ変更中もデータベースの可用性を維持します。
- 並行処理:DML (データ操作言語) 処理を同時に実行できます。
- 段階的アプローチ:変更を複数のステージに分けて実行し、影響を最小限に抑えます。
MySQLの移行を検討している場合、ネイティブなMySQLが得意とする領域と、分散エンジンがより強固な保証を追加できる領域を理解しておくことが重要です。
MySQLのオンラインDDLの仕組み:強みとトレードオフ
MySQLのオンラインDDLの挙動は、主にALTER TABLEのアルゴリズムとLOCK設定によって制御されます。
- アルゴリズム:
- ALGORITHM=COPYは、テーブルをコピーして再構築します。最も安全ですが、影響が大きく処理も遅いです。
- ALGORITHM=INPLACEは、ライブテーブルと並行して構造を変更します (例:シャドーインデックスを作成し、バックグラウンドでデータをバックフィル)。その後メタデータを切り替えるため、テーブル全体のコピーは不要です。
- ALGORITHM=INSTANT (MySQL 8.0以降) に対応する操作 (例:末尾へのカラム追加) の場合、メタデータのみを更新します。データのバックフィルやテーブル再構築は行わないため、ほぼ即時に完了します。
- 同時実行性 (LOCK):
- LOCK=NONEは、操作中も読み書きトラフィックを維持し、開始時とコミット時のみ短時間のメタデータロックが発生します。
- LOCK=SHAREDは、読み取りは許可しますが、重要なタイミングで書き込みが制限されます。
- LOCK=EXCLUSIVEは、読み取り・書き込みの両方を操作期間中ブロックします (通常はCOPYと組み合わせて使用)。
段階的フロー (INPLACE) の例:
- 準備:短時間のメタデータロックを取得し、計画された変更を記録。バックグラウンドワーカーを起動。
- 再編成 (バックグラウンド):新しい構造 (例:インデックスのバックフィル) を構築しながらDMLは継続。新規・更新行も反映されるよう変更を追跡。
- コミット:短時間のメタデータロックを取得し、ポインタを新しい構造にアトミックに切り替え、ロックを解除。
ALGORITHM=INSTANTを使用すると、サポートされている変更 (特にテーブル末尾へのカラム追加や、MySQL 8.0以降の一部セカンダリインデックスのメタデータ操作など) は、データディクショナリのみが変更されるため、数ミリ秒で完了します。テーブルのコピーやバックフィルは発生せず、操作中に保持されるロックも短時間のメタデータロックのみです。ただし制限があります (例:カラムは末尾に追加する必要がある、特定のデータ型や位置の変更は依然としてINPLACEやCOPYが必要)。
適切なアルゴリズムとロックレベルを選択することで、スキーマ変更を最小限のレイテンシ影響とほぼゼロのダウンタイムで実行できます。
メタデータロックとノンブロッキングなスキーマ変更の理解
MySQLのInnoDBエンジンでは、テーブルへのアクセスをブロックせずに多くのスキーマ変更が可能です。たとえば、カラムの追加やインデックスの作成は、テーブル全体をロックすることなく実行できます。

- メタデータの更新:MySQLはテーブルのメタデータを更新し、新しいカラムを追加します。
- バックグラウンド処理:InnoDBエンジンがバックグラウンドで新しいカラムの追加を実行します。既存の行は徐々に新しいカラムを含むように更新されますが、読み取りや書き込み操作はブロックされません。
- 並行操作:バックグラウンドタスクが実行されている間も、テーブルは他の操作に対して完全にアクセス可能です。新しいデータは追加されたカラムを含み、既存データも段階的に更新されます。
オンラインインデックス作成とインスタントDDL
MySQLでは、インデックスを並行して作成することが可能です。つまり、インデックス作成中もテーブルは読み書き可能な状態が維持されます。

- メタデータの準備:MySQLはインデックス定義をテーブルのメタデータに追加します。
- インデックス構築プロセス:InnoDBエンジンがバックグラウンドでインデックスを構築します。既存のテーブルデータを読み取り、インデックスを段階的に作成します。
- 最小限の影響:インデックス構築中もテーブルはアクセス可能です。クエリや更新はブロックされず、インデックスは完全に構築・有効化された後にのみ使用されます。
TiDBがオンラインDDLを再定義する:スケーラブル、分散、即時反映
MySQLの最適なオンラインDDLは非常に優れています。特にALGORITHM=INSTANTやINPLACEを使った場合です。しかし、根本的には単一ノード上での同時実行に限られ、短時間のメタデータロックやテーブル内ローカルのバックフィルに依存しています。一方、TiDBはMySQLのオンラインDDLの利点を受け継ぎつつ、分散SQL環境に拡張しています。具体的には、スキーマ変更は複数ノードにまたがって調整され、バックフィルはクラスタ全体で並列化かつ制御され、ホットスポットや長時間のメタデータロックを発生させることなく、読み書き操作が継続されます。
前述のとおり、TiDBはマルチノードクラスタ向けに適応された3段階のスキーマ変更プロトコル (準備 → 再編成 → コミット) を実装しています。
- 準備:DDLオーナーが短時間のメタデータリースを取得し、変更内容を記録した上で、新しいディスクリプタ (例:シャドウインデックスやカラム) を登録します。これにより、DML操作は安全に継続できます。
- 再編成:バックグラウンドのワーカーが、複数のリージョンやストアにまたがって並列にバックフィルと検証を行います。この間も通常の読み取り・書き込みはMVCCの下で継続され、レート制限によりp95 / p99レイテンシが保護されます。
- コミット:クラスタ全体でメタデータの切り替えをアトミックに実行し、新しい構造を有効化します。この際にかかるのは短時間の分散メタデータロックのみで、各ノードは最大1つのDDLバージョンだけ遅れる可能性がありますが、トラフィックをブロックすることなく追いつくことができます。
テーブルを停止する代わりに、TiDBはクラスタで選出されたDDLオーナー、メタデータのバージョン管理、MVCCを用いて、作業が進行する間もライターやリーダーが一貫したスキーマを参照できるようにします。スケジューラーはリーダー間でバックフィルを分散させてホットストアを回避し、組み込みのスロットル機能によって負荷の高い変更時でもOLTPを安定させます。
実際に得られる効果:
- 可用性の高さ:スキーマ変更中も読み書きが継続可能で、メタデータの調整は瞬間的にのみ発生。
- スケーラビリティ:大規模で分散したデータセットに対し、並列かつリージョンを意識したバックフィルと検証を実行。
- 運用の柔軟性:テールレイテンシが予測可能で、一般的な変更にメンテナンス時間は不要。そのため、機能開発を犠牲にすることなく、機能と並行してスキーマを展開できる。
TiDBの三段階スキーマ変更プロトコルの解説
TiDBはオンラインDDL操作を処理するために、三段階のアプローチを採用しています。
1. 準備フェーズ:
- TiDBはメタデータを更新し、スキーマ変更の準備を行います。
- 変更がクラスタ全体に安全に伝播することを保証します。
2. 再編成フェーズ:
- 実際の変更はバックグラウンドで適用されます。
- 例えば、新しいインデックスの作成やカラムの追加を段階的に行います。
- 同時にDML操作も可能で、データベースは常時稼働したままです。
3. コミットフェーズ:
- スキーマ変更が最終確定され、有効化されます。
- メタデータが更新され、新しいスキーマが反映され、変更が可視化されます。
ステップごとの解説:TiDBがインスタントDDL変更を実行する流れ
本章では、TiDBにおけるオンラインDDL操作の一般的な例を見ていきます:
- メタデータの更新
- バックグラウンド処理
- 最終コミット
ゼロダウンタイムでのカラム追加
TiDBでカラムを追加する場合、テーブルロックを避けつつ、常時利用可能な状態を維持します。技術的には以下のように動作します:
- 準備フェーズ:TiDBはテーブルのメタデータを更新し、新しいカラム定義を追加します。この変更はクラスタ内の全ノードに伝播され、一貫性が保たれます。
- 再編成フェーズ:新しいカラムはバックグラウンドで追加されます。TiDBはバックグラウンドタスクを使用して、既存の行に対してカラムデータを段階的にバックフィルします。このフェーズ中もテーブルは読み書き可能で、新しい書き込みには新しいカラムデータが含まれます。
- コミットフェーズ:バックフィルが完了すると、TiDBはスキーマ変更を最終確定します。メタデータが更新され、新しいスキーマが反映されることで、新しいカラムがすべての後続操作で完全に有効かつ利用可能になります。
このアプローチにより、TiDBは長時間のロックなしでカラムを追加でき、進行中の操作への影響を最小限に抑えることができます。

TiDBでのインデックス即時反映
TiDBでのインデックス作成も、オンラインDDLの恩恵を受ける代表的な操作です。このプロセスにより、クエリや更新はスムーズに継続されます:
- 準備フェーズ:TiDBはインデックス作成の準備として、メタデータを更新し、変更がクラスタ全体に反映されることを確認します。
- 再編成フェーズ:インデックスはバックグラウンドで構築されます。TiDBは既存データを処理してインデックスを段階的に作成しながら、読み取りおよび書き込み操作を同時に行えるようにします。
- コミットフェーズ:新しいインデックスが最終確定され有効化されます。メタデータが更新され、インデックスはクエリ最適化に利用可能となり、ダウンタイムを発生させずにパフォーマンスを向上させます。

大規模な列の変更を安全に実施する
列の変更 (型や属性の変更など) もTiDBでは同様に効率的に処理されます。
- 準備フェーズ:TiDBはテーブルのメタデータを更新し、列定義の変更内容を反映します。
- 再編成フェーズ:実際のデータ変換がバックグラウンドで行われます。たとえば、列の型をINTからBIGINTに変更する場合、既存データを段階的に変換しつつ、テーブルの読み書きは引き続き可能です。
- コミットフェーズ:スキーマ変更が最終確定されます。メタデータが更新され、新しい列の型変更が完全に反映されます。

代替ツール:より安全なスキーママイグレーションのためのgh-ostとpt-osc
MySQL (またはMySQL互換環境) を利用していて、特定の変更でネイティブのオンラインDDLに頼れない場合、実績のあるオンラインスキーマ変更ツールとしてgh-ost (GitHubのオンラインスキーママイグレーションツール) とpt-online-schema-change (Percona Toolkit) が利用できます。どちらもシャドウテーブルを作成し、バックグラウンドでデータをバックフィルし、トリガーやイベントフックで書き込みを反映させた後、最小限の中断で切り替えを行います。異なる点は、接続方法、どの程度自動化されるか、負荷下での挙動にあります。
使い分け (簡単に):
- gh-ost:トリガーを少なくしたい場合、binlogストリーム経由での制御がしやすい場合、スロットリングや一時停止が簡単な場合、フックや切り替えフラグなど豊富な自動化機能が必要な場合、負荷の高いマスターでも安全に動作させたい場合に最適。
- pt-osc:多くのMySQLバージョン、特に古い環境でも動作する成熟したツールが必要な場合、トリガーベースの同期や簡単なスロットリングで問題ない場合に適しています。
機能比較
| 機能 | gh-ost | pt-online-schema-change |
|---|---|---|
| バックフィル方法 | シャドウテーブルに変更を複製する際、binlogを利用。トリガーへの依存は最小限。 | 元のテーブルに行レベルトリガーを設置して、DMLをシャドウテーブルに反映。 |
| 切り替え (カットオーバー) 挙動 | 制御された低レイテンシのカットオーバー。自動リトライ可能。完全自動化または手動承認可。 | クイックリネームでのカットオーバー。通常は短時間のメタデータロック。手動での安全策設定可能。 |
| 負荷下での速度 | Generally faster on busy masters 高負荷のマスターでも高速 (binlog駆動でトリガーオーバーヘッドが少ない)。 | スループットは良好だが、非常に高負荷のテーブルではトリガーがオーバーヘッドになる場合あり。 |
| ダウンタイム | ほぼゼロ (リネーム時に数ミリ秒)。短時間の停止にも耐性あり。 | ほぼゼロ (リネーム時に数ミリ秒)。ロック取得状況に依存。 |
| スロットリング・安全性 | レプリケーション遅延、負荷平均、カスタムフックによるスマートスロットリング内蔵。一時停止・再開も容易。 | レプリケーション遅延や負荷に応じたスロットリング可能。ただしgh-ostほど細かくは制御できない。 |
| 自動化・CI / CD対応 | 充実:事前 / 事後チェック用フック、ステータスAPI、ドライラン、パイプラインのスクリプト化容易。 | 安定:コマンドライン駆動、スクリプト化が一般的。ネイティブフックは少なめ。 |
| 運用の複雑さ | 中程度。binlogアクセスと適切な権限が必要。 | 参入障壁は低め。トリガー依存 (独自の注意点あり) |
| 最適な用途 | 大規模/非常にアクティブなテーブル、正確なスロットリングと安全なカットオーバーが必要な場合 | 広範なMySQL環境、古いバージョン、トリガーベースの同期に慣れたチーム向け |
ゼロダウンタイムでのスキーマ変更のベストプラクティス
ゼロダウンタイムDDLは単一のコマンドではありません。スキーマの進化を他の本番リリースと同様に扱う、規律あるプロセスです:同時実行性を考慮して設計し、現実的な負荷でテストし、展開中はモニタリングし、カットオーバー後に検証します。
以下の原則を基本として押さえましょう:
- 同時実行性を意識した設計:実際の読み書きが継続される前提で設計します。長時間のメタデータロックを避けるアルゴリズムやモードを選び、バックグラウンドでのバックフィルにスロットリングを併用します。
- DDL前にテスト:本番規模 (行数、インデックス、データ偏り) をステージング環境で再現し、代表的なトラフィックをリプレイして実行計画のリグレッションやロック競合を事前に検出します。
- リアルタイムでのモニタリング:p95 / p99レイテンシ、エラー率、レプリケーション遅延、バックフィルスループットを追跡し、安全に一時停止できる中止条件を設定します。
- 前進またはロールバック:すべてのマイグレーションには、迅速に実行可能で文書化されたロールバック (またはフォールフォワード) の手順を用意します。
エンジニア用チェックリスト
- 同時実行性の検証
- アルゴリズム / モードがオンライン変更をサポートしていることを確認 (例:INSTANT / INPLACEまたは同等の手法)。
- 読み書き混在の負荷テストを実施し、バックフィル中もp95 / p99がSLO内に収まることを確認。
- 作業開始前にホットパーティション / リージョンやリーダーの偏りをチェック。
- モニタリング計画
- レイテンシ、エラー、キュー深度 / バックフィル速度、レプリケーション遅延のダッシュボードを用意。
- 厳格な中止条件を伴うアラート設定 (例:p99 > SLO +10%がN分続く場合)。
- 影響を受けるサービスのタイムアウトやリトライのログサンプリング。
- ロールバック戦略
- 事前に戻し用スクリプトを作成 (名前の巻き戻し、シャドウ構造の削除、機能フラグの無効化など)。
- データの安全性を確認 (バックアップ / スナップショット未検証で破壊的変換を行わない)。
- コミュニケーション計画:誰が「緊急停止ボタン」を押せるか、どの条件下で行うかを明確化。
- 自動化とツール活用
- 再実行可能で、ドライランや再開をサポートするマイグレーションフレームワーク / ランナーを使用。
- レイテンシや遅延に応じたレート制限などスロットリング制御、停止/再開フックを活用。
- 前後チェック:インデックスカバレッジ、実行計画差分、メタデータロック時間。
- 変更後の検証
- 前後の実行計画を比較し、ホットパスでの性能劣化の有無を確認。
- 新しい構造 (例:インデックス採用) が正しく使われているか、バックフィルが完了しているかを検証。
- ランブック、ダッシュボード、キャパシティモデルを更新し、学んだ教訓を反映。
課題と考慮点
TiDBのオンラインDDLには多くの利点がありますが、潜在的な課題や注意点を把握しておくことも重要です。これらを理解することで、スキーマ変更の計画や実行をより効果的に行えます。本節では、リソース使用への影響、複雑なスキーマ変更の難しさ、オンラインDDLをTiDBで利用する際のバージョン互換性の重要性について解説します。
- リソース使用:オンラインDDL操作はリソースを多く消費する可能性があります。パフォーマンス問題を防ぐため、リソースのモニタリングと管理が重要です。
- 複雑なスキーマ変更:一部の変更は、慎重な計画と実行が必要です。
- バージョン互換性:必要なオンラインDDL操作がサポートされているTiDBのバージョンを確認してください。
結論:TiDBで構築する、耐障害性の高いMySQLワークロード
オンラインDDLはもはやオプションではなく、現代のチームが稼働時間やパフォーマンス、開発スピードを犠牲にせずにスキーマを進化させるための方法です。TiDBの三段階プロトコル (準備 → 再編成 → コミット)、分散型の同時実行制御、バックグラウンドでのバックフィルにより、変更中も読み書きは途切れず、大規模なMySQL互換環境でも安全かつ予測可能にスケールできます。
TiDBのオンラインDDL、高可用性、そして弾力的なスケーリングを活用することで、組織は以下を得られます:運用の柔軟性 (業務時間中でもスキーマ変更を実施可能)、パフォーマンスの安定性 (p95 / p99のレイテンシがSLO内に収まる)、そして成長へのよりスムーズな道筋 (メンテナンスウィンドウ不要、緊急対応も減少)。その結果、地域やテナント、さまざまなワークロードにまたがって、高速に動作するアプリケーションを支える耐障害性の高いデータ層が実現します。
データベース運用の効率性と信頼性を向上させたいですか?無料のTiDB Cloudクラスタを立ち上げて、オンラインDDLやローリング変更、負荷下でのパフォーマンスを検証してみましょう。
TiDB Cloud Dedicated
TiDB Cloudのエンタープライズ版。
専用VPC上に構築された専有DBaaSでAWSとGoogle Cloudで利用可能。
TiDB Cloud Starter
TiDB Cloudのライト版。
TiDBの機能をフルマネージド環境で使用でき無料かつお客様の裁量で利用開始。