周二做了个主从切换,然后半夜被RD打电话叫起来,说插入主键报重复主键错误,我登录到机器上一看,表中的最大主键ID确实大于表的auto_increment值,临时处理了下,先恢复业务,那为什么会出现这种情况?第二天和RD沟通后,他们业务中有replace操作,我怀疑这个操作会导致主从auto_increment不一致。
试验:
构造表结构和数据
|
|
进行replace操作
|
|
我们看到replace操作,有2行被影响,auto_increment自动+1,网上查资料得知:对于已经存在的数据,replace操作相当于进行update操作,而update实际是delete+insert两个连续操作,insert会导致auto_incement+1,但是binlog只会产生一条update语句。
|
|
|
|
至此主从auto_increment的不一致的原因已经定位到。
隐患点:
主从切换后,业务如有replace操作,可能造成新主库写入失败。
如何解决?
先了解下算法:MySQL对于auto_increment的算法是select max(id)+1 from t的方法来拿到auto_inrement的值。
淘宝的分享解释:
|
|
解决办法
- 重启从库,所有表的auto_increment会修正。
- 插入新数据后,自增值自动追平,主库replace后如果有insert语句,这样会自动追平的。
延伸
- insert into .. on duplicate key update语句 碰到表中已经存在要replace的数据,也会导致主从auto_increment不一致