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可以順利完成。
適用範圍
資料庫版本需滿足以下要求才能開啟DDL唯一鍵衝突最佳化功能,當版本不符合要求時,可以升級資料庫大版本或核心小版本:
MySQL 8.4
MySQL 8.0且核心小版本大於等於20250531
使用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