故障案例:MySQL唯一索引有重复值,官方却说This is not a bug

  • GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。
  • GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。
  • 作者:飞鱼过天
  • 文章来源:GreatSQL社区原创


  • 问题
  • 原因
  • 故障解决方案
  • 复现步骤
  • 参考文献

一、问题:

MySQL5.7.38主从架构,主节点唯一索引上(唯一索引不是主键)有重复值,全部从节点报1062,SQL线程状态异常,根据SQL线程报的binlog位置点,insert 数据时有重复值,插入失败

二、原因:

unique_checks=0时导致,在bug(106121)列表中官方解释的原因:该参数关闭,维护唯一索引时,不会进行物理读,只会进行内存读,来确保唯一索引的唯一性,即如果内存中有冲突数据就报1062,如果内存中没有冲突数据插入成功,不会进行io来将唯一索引相关的数据页拉取到内存。

官方的回复“IMHO this is not a bug”,我理解的意思“不要你觉得,我要我觉得,我就是这么玩的”。

三、故障解决方案:

一、临时解决方案

  • 恢复主从:

缺点是:不能够解决数据重复的问题,切换主从后会面临更多重复数据的问题,如果从节点接收查请求且使用到了原唯一索引的字段,那sql效率会严重下降,但是可以解决主从复制停止的问题

二、永久解决方案

  1. 业务自己去重,不要插入重复数据
  2. 参数unique_checks保持为1
  3. 关于重复的业务数据:与业务交流,确定重复数据的处理方式

四、复现步骤:

1. 表结构:

mysql> create database wl; mysql> show create table wl.lgf\G *************************** 1. row *************************** Table: lgf Create Table: CREATE TABLE `lgf` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120) NOT NULL DEFAULT '', `pad` char(60) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `c` (`c`,`pad`) ) ENGINE=InnoDB AUTO_INCREMENT=2147483647 DEFAULT CHARSET=utf8