场景描述
在使用云数据库 MySQL 的过程中,备实例或只读实例出现复制中断,提示如下错误:
[ERROR] [MY-010584] [Repl] Slave SQL for channel '': Worker 1 failed executing transaction 'XXX' at master log mysql-bin.XXX, end_log_pos XXX; Could not execute Write_rows_v1 event on table XXX.XXX; Duplicate entry 'XXX' for key 'xxx.xxx', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.XXX, end_log_pos XXX, Error_code: MY-001062
原因分析
将 unique_checks 设置为0时,可能造成上述错误。
unique_checks 参数的取值含义:
取值为1:云数据库 MySQL 会对 InnoDB 表中的唯一键进行唯一性检查。
取值为0:如果 DML 语句操作的数据不在 buffer pool 中,那么云数据库 MySQL 不会通过读取磁盘上的主键和唯一键来对 InnoDB 表中的二级索引进行唯一性检查。此时,可以插入重复的唯一键。
当在主实例上,设置 unique_checks 为0时,如果 DML 语句操作的数据不在 buffer pool 中,那么云数据库 MySQL 不会通过读取磁盘上的主键和唯一键来对 InnoDB 表中的二级索引进行唯一性检查,此时主实例将成功插入重复的唯一键。而在备实例上,设置 unique_checks 为0时,如果 DML 语句操作的数据存在于 buffer pool 中,云数据库 MySQL 将会对 DML 语句所操作的二级索引进行唯一性检查,此时不允许插入重复的唯一键,从而发生复制中断。详情请参见 MySQL 官方 Bug#106121。
解决思路
先确认实例的 unique_checks 参数值,再根据实际情况来修改参数值。
如果您确定插入的数据不会产生唯一键冲突,那么可以设置 unique_checks 为0,以加快数据的导入速度。
如果您不确定插入的数据是否会产生唯一键冲突,那么请设置 unique_checks 为1。
处理步骤
unique_checks 是 MySQL 用于控制 InnoDB 在插入数据时是否做唯一性检查的参数。它是动态变量,可以在线修改,无需重启。
1. 通过 MySQL 客户端连接目标云数据库 MySQL 实例。
2. 参考如下命令,查询当前的参数值。
SELECT @@unique_checks; -- 查看会话值SHOW VARIABLES LIKE 'unique_checks'; -- 查看(默认会话)
3. 根据需要,修改参数值,修改的命令可参考:
-- 会话级(只对当前连接生效,最常用)SET unique_checks = 0; -- 关闭唯一性检查SET unique_checks = 1; -- 开启(默认值)等价写法:SET SESSION unique_checks = 0;SET @@session.unique_checks = 0;