すべてのプロダクト
Search
ドキュメントセンター

Data Management:ロックフリーのスキーマ変更

最終更新日:Nov 09, 2025

ロックフリーのデータ定義言語 (DDL) 変更は、スキーマ変更中にテーブルがロックされるのを防ぎます。この機能は、テーブルのロックによるサービス中断を回避し、ネイティブのオンライン DDL で発生する可能性のあるアクティブ/スタンバイリンクのレイテンシーを防ぎます。オフピーク時にロックフリーの変更を送信することをお勧めします。

背景情報

大規模なテーブルのスキーマを変更する場合、テーブルロックのリスクを考慮する必要があります。ロックされたテーブルは書き込み操作を防ぎます。ネイティブの MySQL は、次の機能を提供します。

  • MySQL 5.5 以前では、DDL は 2 つの実行アルゴリズムを提供します。

    • Table-Copy: このアルゴリズムは、データを一時テーブルにコピーすることで変更を加えます。このプロセス中、ソーステーブルはロックされ、書き込み操作は許可されません。

    • In-Place (MySQL 5.5 以降で利用可能): このアルゴリズムは、実行中にデータベースでの読み取りおよび書き込み操作を許可します。ただし、インデックス関連の変更のみをサポートします。

  • MySQL 5.6 以降では、DDL は Innodb-OnlineDDL も提供します。Innodb-OnlineDDL の詳細については、「Innodb-OnlineDDL」をご参照ください。

    この機能は、列の追加、削除、名前変更、インデックスの追加や変更など、幅広い DDL タイプをカバーしています。ただし、列の型の変更、列の長さの変更、文字セットの変更など、一部の一般的な DDL タイプはカバーしていません。

シナリオ

サポートされるデータベースタイプ

RDS for MySQLPolarDB for MySQLMyBase for MySQL、およびその他の自己管理 MySQL データベース。

特徴

  • ネイティブのデータベース機能と比較して、DMS のロックフリーのスキーマ変更機能を使用すると、変更の実行速度を制御できます。これにより、アクティブ/スタンバイリンクでのレイテンシーを回避し、データベースパフォーマンスへの影響を最小限に抑え、ネイティブのオンライン DDL がテーブルをロックする多くのシナリオをサポートします。

  • pt-online-schema-change や OSC などの他のツールと比較して、DMS のロックフリーのスキーマ変更機能はトリガーに依存しません。この機能は、非同期実行中のデータベースへの影響が最小限であり、いつでも安全に中断できます。

  • DMS のロックフリーのスキーマ変更機能は DTS との互換性が高いです。変更中のテーブルに DTS テーブルレベルのレプリケーションリンクがある場合、DMS のロックフリーのスキーマ変更機能を使用しても DTS レプリケーションは中断されません。

    説明

    DTS レプリケーションリンクは 2020 年 2 月 14 日以降に再起動されている必要があります。

  • 次の表は、ネイティブの MySQL Online DDL と DMS のロックフリーのスキーマ変更機能の機能を比較したものです。

    サポートされる項目

    MySQL 5.5 以前

    MySQL 5.6 以降

    DMS ロックフリーのスキーマ変更

    列の追加

    いいえ

    はい

    Y

    列の削除

    いいえ

    はい

    はい。

    列の名前変更

    いいえ

    はい

    はい

    インデックスの追加

    N

    はい

    はい。

    インデックスの変更

    いいえ

    はい

    はい

    デフラグ操作

    N

    はい

    はい

    列の型の変更

    N

    N

    はい

    列の長さの変更

    いいえ

    N

    はい

    文字セットの変更

    N

    いいえ

    はい

    文字セットの変換

    いいえ

    いいえ

    Y

    タイムゾーン修正操作

    N

    いいえ

    はい。

    セカンダリデータベースのレイテンシーの軽減または排除

    いいえ

    いいえ

    はい

    • いいえ: サポートされていません。

    • はい: サポートされています

DMS のロックフリーのスキーマ変更機能と他のソリューションとの比較については、「ロックフリーのスキーマ変更ソリューションの比較」をご参照ください。

注意

  • DMS は、既存のパーティションテーブルのスキーマ変更をサポートします。

  • ロックフリーのスキーマ変更機能は、単一の変更チケット内で同じデータベース内の複数のテーブルの変更をサポートします。

    チケットで変更 SQL を設定するときは、セミコロン (;) を使用して、異なるテーブルの SQL 文を区切ります。

  • プライマリキーまたは一意キーのみを持つテーブルでロックフリーのスキーマ変更を実行する場合、プライマリキーまたは一意キーを更新しないでください。そうしないと、変更タスクは失敗します。

  • 米国リージョンの DMS はこの機能をサポートしていません。

仕組み

ロックフリーのスキーマ変更チケットを送信すると、DMS は自動的に次の操作を実行して、テーブルをロックせずに変更を完了します。

  1. 一時テーブルの作成: DMS は、ソーステーブルと同じスキーマを持つ一時テーブルをターゲットデータベースに作成します。このテーブルはデータのコピーに使用されます。

    SQL 構文は CREATE TABLE tmp_table_name LIKE table_name です。

  2. 一時テーブルのスキーマの変更: 一時テーブルのスキーマが指定どおりに変更されます。

    SQL 構文は ALTER TABLE tmp_table_name XXXX です。

  3. 完全データの同期: ソーステーブルの完全データが一時テーブルに同期されます。

    SQL 構文は INSERT IGNORE INTO tmp_table_name (SELECT %s FROM table_name FORCE INDEX (%s) WHERE XXX LOCK IN SHARE MODE) です。

  4. バイナリログファイルの解析と増分データの同期: ソーステーブルからの増分データが一時テーブルに同期されます。

    SQL 構文は UPDATE/INSERT/DELETE tmp_table_name です。

  5. テーブルの切り替え: ソーステーブルはバックアップとして名前が変更され、一時テーブルがソーステーブルを置き換えます。

    SQL 構文は RENAME TABLE table_name to old_tmp_table_name, tmp_table_name to table_name です。

説明

tmp_table_name は一時テーブル名の例です。実際の一次テーブル名は、ロックフリー変更のタスク進捗セクションで確認できます。詳細については、「ロックフリー変更の進捗状況の表示」をご参照ください。

次の一覧は、一時テーブル名のフォーマットを説明しています。

  • データテーブル: `tp_{Change_ID}_ogt_{Source_Table_Name}`、`tp_{Change_ID}_g_{Source_Table_Name}`

  • ハートビートテーブル: `tp_{Change_ID}_ogl_{Source_Table_Name}`、`tp_{Change_ID}_l_{Source_Table_Name}`

  • 切り替え前の補助テーブルと切り替え後のソーステーブル: `tp_{Change_ID}_del_{Source_Table_Name}`、`tp_{Change_ID}_d_{Source_Table_Name}`

  • テーブルロック検出: `tpa_xxx_xxx`

説明

変更 ID は、内部 DMS エンジンの実行 ID です。チケット番号やタスク番号ではありません。

リファレンス

よくある質問

  • Q: ロックフリーのスキーマ変更はサービスに影響しますか?

    A: 通常の状況では、サービスに影響はありません。ただし、プロセスにはデータコピーが含まれるため、インスタンスのパフォーマンスにわずかな影響があります。

  • Q: ロックフリー変更チケットで CREATE_INDEX を実行してインデックスを追加するとエラーが報告されます。DMS はインデックスの追加をサポートしていませんか?

    A: はい、DMS はインデックスの追加をサポートしています。`CREATE_INDEX` でエラーが発生した場合は、`ALTER TABLE` 文などの代替メソッドを使用できます: ALTER TABLE `table_name` ADD INDEX index_name ( `column` ) ;