RDS MySQL对DDL执行过程中唯一键冲突问题进行了优化,有效减少了该问题导致的DDL失败,提升了DDL的成功率。
功能说明
背景:MySQL的Online DDL允许在DDL期间对目标表进行写入、更新和删除,并将表的修改操作记录到row log中。在DDL执行完成前,系统会应用DDL期间产生的row log,将增量数据补全到新的数据文件中。如果执行DDL的数据表中存在唯一索引,且在DDL执行期间的修改操作中出现了唯一键冲突,row log应用阶段就会出错,导致整个DDL执行失败。由于row log的应用发生在DDL执行完成前,因此该问题导致的DDL失败的代价很大。
简介:RDS MySQL针对此问题进行了优化,Online DDL执行过程中发生唯一键冲突时将不会导致DDL失败,整个DDL可以顺利完成。
适用范围
参数管理
参数说明
您可以通过设置参数innodb_online_alter_ignore_dup_key_error_for_uk来开关DDL唯一键冲突优化功能。
参数名称 | 说明 |
|
|
修改参数
访问RDS实例列表,在上方选择地域,然后单击目标实例ID。
在左侧导航栏中单击参数设置。
在可修改参数页签内搜索待修改参数,并配置参数值。
单击确定,然后单击提交参数,并在弹出的窗口中选择生效的时间段。
功能效果
测试方法
您可以通过以下步骤,测试开启与关闭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 ; -- 循环 100000 次重复插入 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