ApsaraDB RDS for MySQL は、DDL 実行中の一意キーの競合の処理を最適化します。これにより、障害が減少し、DDL 操作の成功率が向上します。
仕組み
背景: MySQL のオンライン DDL では、DDL 操作中にターゲットテーブルに対して書き込み、更新、削除を同時に実行できます。これらの変更は行ログに記録されます。DDL が完了する直前に、エンジンは行ログを適用して新しいデータファイルを更新します。テーブルに一意インデックスがあり、DDL 操作中に生成された変更で一意キーの競合が発生した場合、行ログの適用は失敗し、DDL 操作全体も失敗します。行ログの適用は DDL が完了する直前に行われるため、この段階での失敗はコストが高くなります。
概要: ApsaraDB RDS for MySQL はこの動作を最適化します。この最適化を有効にすると、オンライン DDL 中に発生する一意キーの競合によって DDL 操作が失敗することはありません。
注意事項
DDL の一意キー競合の最適化を有効にするには、データベースインスタンスが次のいずれかのバージョン要件を満たしている必要があります。インスタンスがこれらの要件を満たしていない場合は、メジャーエンジンバージョンをアップグレードするか、マイナーエンジンバージョンをアップグレードしてください。
MySQL 8.4
マイナーエンジンバージョンが 20250531 以降の MySQL 8.0
DDL の一意キー競合の最適化を使用する場合、次の制限事項があります:
プライマリキーを変更する DDL 操作はサポートしていません。
DDL 操作中に作成された一意インデックスでの競合はサポートしていません。
この機能は、仮想列を含む一意インデックスや多値一意インデックスをサポートしていません。
パラメータ管理
パラメータ
innodb_online_alter_ignore_dup_key_error_for_uk パラメータを設定することで、DDL の一意キー競合の最適化を有効または無効にできます。
パラメータ | 説明 |
|
|
パラメータの変更
- RDSインスタンスにアクセスし、上部のリージョンを選択し、対象のRDSインスタンスのIDをクリックします。
ナビゲーションペインで、[パラメータ設定] をクリックします。
[編集可能なパラメータ] タブで、対象のパラメータを見つけてその値を設定します。
[OK] をクリックし、次に [パラメータの送信] をクリックします。表示されるダイアログボックスで、変更がいつ有効になるかを選択します。
機能の検証
テスト手順
DDL の一意キー競合の最適化が有効な場合と無効な場合で DDL 実行の動作をテストするには、次の手順に従ってください:
一意キーを持つテーブルを作成し、データを挿入します。
-- 一意キーを持つテーブルの作成 CREATE DATABASE IF NOT EXISTS test_db; USE test_db; DROP TABLE IF EXISTS unique_test; CREATE TABLE unique_test ( id INT AUTO_INCREMENT PRIMARY KEY, user_id VARCHAR(50) NOT NULL, name VARCHAR(100), UNIQUE KEY uk_user_id (user_id) ); -- 初期データの挿入 (例: 2,000,000行) DELIMITER $$ DROP PROCEDURE IF EXISTS insert_initial_data $$ CREATE PROCEDURE insert_initial_data(IN num_rows INT) BEGIN DECLARE i INT DEFAULT 1; START TRANSACTION; WHILE i <= num_rows DO SET @uid = CONCAT('user_', i); SET @name = CONCAT('Name_', i); INSERT INTO unique_test (user_id, name) VALUES (@uid, @name); SET i = i + 1; END WHILE; COMMIT; END $$ DELIMITER ; CALL insert_initial_data(2000000);セッションを開始し、重複する値を継続的に挿入して、一意キーの競合をトリガーします。
USE test_db; DELIMITER $$ DROP PROCEDURE IF EXISTS insert_duplicate_loop $$ CREATE PROCEDURE insert_duplicate_loop( IN loop_count INT ) BEGIN DECLARE i INT DEFAULT 0; DECLARE CONTINUE HANDLER FOR 1062 BEGIN END; -- 重複キーエラーを無視 WHILE i < loop_count DO -- 既存の user_id を挿入して一意キーの競合をトリガー INSERT INTO unique_test (user_id, name) VALUES ('user_1', 'ConflictUser'); SET i = i + 1; END WHILE; END $$ DELIMITER ; -- 100,000 回ループして重複データを挿入 CALL insert_duplicate_loop(100000);別のセッションを開始して、DDL の一意キー競合の最適化が有効な場合と無効な場合の DDL 実行動作をテストします。
ALTER TABLE test_db.unique_test ENGINE = InnoDB;
テスト結果
DDL の一意キー競合の最適化が無効な場合、DDL 操作は失敗し、エラーが返されます。
-- innodb_online_alter_ignore_dup_key_error_for_uk = OFF の場合 mysql> ALTER TABLE test_db.unique_test ENGINE = InnoDB; ERROR 1062 (23000): Duplicate entry 'user_1' for key 'unique_test.uk_user_id'DDL の一意キー競合の最適化が有効な場合、DDL 操作は正常に完了します。
-- innodb_online_alter_ignore_dup_key_error_for_uk = ON の場合 mysql> ALTER TABLE test_db.unique_test ENGINE = InnoDB; Query OK, 0 rows affected (6.03 sec) Records: 0 Duplicates: 0 Warnings: 0