MySQL bug replace into 语句导致主从切换后主键冲突
一、背景
生产环境遇到一个 MySQL 写入报错的问题,业务写入数据时报主键冲突。经过调查,这套 MySQL 集群版本为 Percona 5.7.19,在报主键冲突前,做过主从切换,报主键冲突的SQL语句为 replace into,表的主键是自增列,调查该表的 auto_increment,发现一个很奇怪的问题,该表的 auto_increment 竟然比表数据的 max(id) 还小,难怪会出现主键冲突了。
那么为什么会出现 auto_increment 比 max(id) 还小?搜索一下,发现果然是 MySQL 的一个 Bug,见链接:
https://bugs.mysql.com/bug.php?id=83030
简单来说,replace into 语句通过唯一键相同修改记录时,主库上该表的 auto_increment 会变化,而从库上该表的 auto_increment 值不变。所以在从库上会出现 auto_increment 值比 max(id) 还小的情况,做主从切换之后,写入数据,就可能会发生主键冲突。
二、复现方法
另外也搜索到一篇文章,描述了同样的 Bug 和 复现方法,见链接:
https://developer.aliyun.com/article/57855
拷贝上述链接原文如下:
2.1 复现条件
- MySQL 5.7
- ROW模式
表结构:
CREATE TABLE `test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`col_1` varchar(100) DEFAULT NULL,
`col_2` varchar(100) DEFAULT NULL,
`col_3` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `col_1` (`col_1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8