全部產品
Search
文件中心

ApsaraDB RDS:DDL唯一鍵衝突最佳化

更新時間:May 13, 2026

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唯一鍵衝突最佳化功能。

參數名稱

說明

innodb_online_alter_ignore_dup_key_error_for_uk

  • 描述:開啟或關閉DDL唯一鍵衝突最佳化。

  • 參數範圍:全域參數。

  • 資料類型:Boolean

  • 預設值:ON

  • 取值範圍:ONOFF

  • 是否需要重啟執行個體:否。

修改參數

  1. 訪問RDS執行個體列表,在上方選擇地區,然後單擊目標執行個體ID。

  2. 在左側導覽列中單擊參數設定

  3. 可修改參數頁簽內搜尋待修改參數,並配置參數值。

  4. 單擊確定,然後單擊提交參數,並在彈出的視窗中選擇生效的時間段。

功能效果

測試方法

您可以通過以下步驟,測試開啟與關閉DDL唯一鍵衝突最佳化功能時DDL的執行情況:

  1. 構建包含唯一鍵的資料表並插入資料。

    -- 建立帶有唯一鍵的表
    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);
  2. 啟動一個會話並持續插入重複值,觸發唯一鍵衝突。

    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);
  3. 啟動另一個會話,分別測試開啟與關閉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