ロックレスデータ定義言語 (DDL) 変更により、スキーマ進化中にテーブルがロックされるのを防ぎます。この機能は、ネイティブのオンライン DDL が引き起こす可能性のある業務の中断や、アクティブ/スタンバイリンクでの遅延を回避します。ロックレス変更は、ビジネスのオフピーク時にサブミットすることを推奨します。
背景情報
大規模なテーブルのスキーマを変更すると、テーブルがロックされる可能性があります。ロックされたテーブルは書き込み操作をブロックします。ネイティブの MySQL 機能には、以下が含まれます。
MySQL 5.5 以前のバージョンでは、Table-Copy と In-Place の 2 つの DDL 実行アルゴリズムが提供されています。
Table-Copy:データを一時テーブルにコピーして変更を完了します。変更中、テーブルはロックされ、書き込みはできません。
In-Place (MySQL 5.5 以降で利用可能):このアルゴリズムの実行中、データベースの読み取りと書き込みが可能です。ただし、インデックスに対する操作のみをサポートします。
MySQL 5.6 以降のバージョンでは、Innodb-OnlineDDL も提供されています。Innodb-OnlineDDL の詳細については、「Innodb-OnlineDDL」をご参照ください。
この機能は、列の追加、列の削除、列名の変更、インデックスの追加、インデックスの変更など、幅広い DDL タイプをサポートします。ただし、列の型の変更、列の長さの変更、文字セットの変更など、一部の一般的な DDL タイプはサポートしていません。
シナリオ
データベースのテーブルスキーマの変更。
テーブルの文字セットと照合順序の変更、またはタイムゾーンの調整。
`Optimize Table` 操作によるテーブルのロックを回避し、表領域を再利用して断片化率を低減します。詳細については、「ロックレススキーマ進化による断片化された領域の再利用」をご参照ください。
サポートされるデータベースタイプ
RDS for MySQL、PolarDB for MySQL、MyBase for MySQL、およびその他の MySQL 互換データベース。
特徴
ネイティブのデータベース機能と比較して、DMS のロックレススキーマ進化では、変更の実行速度をコントロールできます。この機能により、データベースパフォーマンスへの影響を軽減し、アクティブ/スタンバイリンクでの遅延を回避し、ネイティブのオンライン DDL がテーブルをロックする多くのシナリオをサポートします。
PT-Online や OSC などの他のツールと比較して、DMS のロックレススキーマ進化はトリガーに依存しません。この機能は、非同期実行中のデータベースへの影響が最小限であり、いつでも安全に中断できます。
DMS のロックレススキーマ進化は、Data Transmission Service (DTS) との互換性が高いです。スキーマ変更中のテーブルに DTS のテーブルレベルのレプリケーションタスクがある場合、DMS を使用してロックレススキーマ進化を行っても、レプリケーションの中断は発生しません。
説明DTS レプリケーションタスクは、2020 年 2 月 14 日以降に再起動されている必要があります。
ネイティブの MySQL オンライン DDL と DMS のロックレススキーマ進化の比較:
サポートされるリソース
MySQL 5.5 以前
MySQL 5.6 以降
DMS のロックレススキーマ進化
列の追加
いいえ
はい
はい
列の削除
いいえ
はい
はい
列の名前変更
いいえ
はい
はい
インデックスの追加
N
はい
はい
インデックスの変更
いいえ
はい
はい
デフラグメンテーション
N
はい
はい
列の型の変更
N
N
はい
列の長さの変更
いいえ
N
はい
文字セットの変更
N
いいえ
はい
文字の変換
いいえ
いいえ
はい
タイムゾーンの調整
N
いいえ
はい
セカンダリデータベースの遅延の削減または解消
いいえ
いいえ
はい
いいえ: サポートされていません。
はい: サポートされています
DMS のロックレススキーマ進化と他のソリューションとの比較については、「ロックレススキーマ進化ソリューションの比較」をご参照ください。
注意事項
DMS は、既存のパーティションテーブルのスキーマ進化をサポートします。
ロックレススキーマ進化は、単一のチケット内で同じデータベース内の複数のテーブルの変更をサポートします。
チケットの変更 SQL を設定する際、異なるテーブルの SQL 文をセミコロン (;) で区切ってください。
プライマリキーのみ、または一意キーのみを持つテーブルでロックレススキーマ進化を実行する場合、そのキーの列を更新しないでください。更新すると、変更タスクは失敗します。
米国 (シリコンバレー) リージョンの DMS は、この機能をサポートしていません。
仕組み
ロックレススキーマ進化のチケットをサブミットすると、DMS は自動的に以下の操作を実行し、テーブルをロックせずに変更を完了します。
一時テーブルの作成:DMS は、元のテーブルと同じスキーマを持つ一時テーブルをターゲットデータベースに作成します。この一時テーブルはデータのコピーに使用されます。
SQL 構文は
CREATE TABLE tmp_table_name LIKE table_nameです。一時テーブルの構造変更:一時テーブルの構造を変更できます。
SQL 構文は
ALTER TABLE tmp_table_name XXXXです。完全データのコピー:DMS は、元のテーブルからすべてのデータを一時テーブルにコピーします。
SQL 構文は
INSERT IGNORE INTO tmp_table_name (SELECT %s FROM table_name FORCE INDEX (%s) WHERE XXX LOCK IN SHARE MODE)です。バイナリログの解析と増分データの同期:DMS は、元のテーブルからの増分データを一時テーブルに同期します。
SQL 構文は
UPDATE/INSERT/DELETE tmp_table_nameです。テーブルの切り替え:DMS は、元のテーブルをバックアップ名に変更し、その後、一時テーブルを元のテーブル名に変更します。
SQL 構文は
RENAME TABLE table_name to old_tmp_table_name, tmp_table_name to table_nameです。
`tmp_table_name` は一時テーブル名の例です。実際の一次テーブル名は、ロックレス変更のタスク進捗ページで確認できます。詳細については、「ロックレス変更の進捗の表示」をご参照ください。
一時テーブル名のフォーマットは以下の通りです。
データテーブル:`tp_{Change_ID}_ogt_{Original_Table_Name}`、`tp_{Change_ID}_g_{Original_Table_Name}`
ハートビートテーブル:`tp_{Change_ID}_ogl_{Original_Table_Name}`、`tp_{Change_ID}_l_{Original_Table_Name}`
切り替え前のヘルパーテーブルと切り替え後の元のテーブル:`tp_{Change_ID}_del_{Original_Table_Name}`、`tp_{Change_ID}_d_{Original_Table_Name}`
テーブルロック検出: `tpa_xxx_xxx`
変更 ID は、DMS 内部エンジンの実行 ID です。チケット番号やタスク番号ではありません。
リファレンス
以下の操作を実行できます。
インスタンスのロックレススキーマ進化機能を有効にします。詳細については、「ロックレススキーマ進化の有効化」をご参照ください。
ロックレススキーマ進化のチケットをサブミットします。詳細については、「チケットを使用したロックレススキーマ進化の実行」をご参照ください。
(オプション) ロックレス変更タスクの進捗を表示します。詳細については、「ロックレス変更の進捗の表示」をご参照ください。
API 操作を使用して、ロックレススキーマ進化のチケットを設定および管理することもできます。
API
説明
ロックレス変更チケットを作成します。
実行ステータスや影響を受けたデータ行数など、ロックレス変更チケットの詳細を照会します。
よくある質問
Q:ロックレススキーマ進化はビジネスに影響しますか?
A:サービスに影響はありません。ただし、変更プロセスにはデータコピーが含まれるため、インスタンスのパフォーマンスにわずかな影響があります。
Q:ロックレス変更チケットで
CREATE_INDEXを実行してインデックスを追加しようとするとエラーが発生しました。DMS はインデックスの追加をサポートしていないのですか?A:DMS はインデックスの追加をサポートしています。次の
ALTER TABLE文を使用してインデックスを追加できます。ALTER TABLE `table_name` ADD INDEX index_name ( `column` ) ;Q:ロックレス変更チケットで
rename columnを実行してフィールド名を変更しようとするとエラーが発生しました。DMS はフィールド名の変更をサポートしていないのですか?A:DMS はフィールド名の変更をサポートしています。次の
ALTER TABLE文を使用してフィールド名を変更できます。ALTER TABLE table_name CHANGE COLUMN old_column_name new_column_name datatype;