一、风险概述
云数据库 MySQL 实例在发生主备切换(HA 切换)后,若你的业务使用了 REPLACE INTO 语法,可能出现 Primary Key Duplicate(主键冲突)报错,导致业务写入失败,在特定版本的 MySQL 内核中存在此缺陷。
二、故障现象
数据库单表在写入时频繁触发主键冲突报错,影响业务成功率。
三、故障原因
某实例采用三节点(A – B – C)高可用架构。该实例发生连续两次 HA 切换,主节点最终由 A 变为 C。切换到 C 节点后,内存中的 AUTO_INCREMENT 计数器低于物理磁盘中已存在的 MAX(id),导致写入新数据时触发主键冲突。
根本原因分析:
·业务使用了 REPLACE INTO 语法。
·在云数据库 MySQL 低内核版本中,REPLACE INTO 在执行“删除 + 插入”过程中,若发生特定并发或未触发计数器持久化,会导致备库的自增元数据未及时更新。
·主备切换后,新主库继承了这个不一致的元数据。
四、受影响版本范围
注意:说明:
注意:以下内核版本之前的版本存在该问题,建议尽快升级。
| MySQL 版本 | 安全的内核版本(已修复该问题) |
| MySQL 5.6 | 云数据库 MySQL 5.6 20201230及之后的版本。 |
| MySQL 5.7 | 社区版本5.7.18:云数据库 MySQL 20190830及之后的版本。社区版本5.7.36:云数据库 MySQL 20220715及之后的版本。社区版本5.7.44的全部版本。 |
| MySQL 8.0 | 全部版本。 |
五、自查方法
如果你使用了 REPLACE INTO 语法,建议检查当前实例内核版本是否在 受影响版本范围 内。
六、规避建议
| 方案 | 说明 |
| 升级内核版本 | 彻底解决问题,新版本已优化 AUTO_INCREMENT 处理逻辑。 |
| 改用 INSERT … ON DUPLICATE KEY UPDATE | 语义更清晰,可避免部分问题。 |
| 业务层处理 | 先查询是否存在,再决定 INSERT 或 UPDATE。 |
七、已发生问题的应急处理
如果实例已经出现主键冲突报错,可采用以下方式临时恢复:
— 方式1:手动调大 AUTO_INCREMENT 值ALTER TABLE `表名` AUTO_INCREMENT = {期望值};– 方式2:重启实例(重启后 MySQL 会自动将 AUTO_INCREMENT 设为 MAX(id)+1)
注意:说明:
注意:即使报主键冲突错误,AUTO_INCREMENT 的值仍会 +1,若偏差较小,失败几次后可能自动恢复正常。
八、根本解决:升级实例的内核版本
通过控制台对实例进行内核版本的升级,操作说明请参见 升级内核小版本。