Replace into 带来的主从自增主键差异
环境
|
|
Master-Slave(Master)
下面我们在主库进行replace操作
|
|
我们看到replace有2行被影响,id=4,insert操作做了一次auto_increment+1
歪个楼,replace操作对于已经存在的数据进行update操作,而update实际是delete+insert两个连续操作,binlog产生一条update语句,这里binlog_format=ROW
|
|
来看看从库
|
|
我们看到replace有2行被影响,id=4,而表没有做auto_increment+1,因为对于从库来说,只做了一次update操作,影响1行
问题1: DB出现切换,新主写入冲突
新数据写进来,报错了,主键冲突
|
|
主键冲突就不说啥了,刚才id没有auto_increment+1,这是必然。但是,insert操作却出发了一次auto_increment+1,为什么?
二次insert,成功
|
|
那么,通过问题3的方法,可以解决主从id一致的问题,对于操作频繁的DB,只要replace后面有insert操作,即可追平,所以如果业务是读写分离的话,应该没啥影响。不过,这是侥幸心理,如果正当replace后出现宕机切换,那么一样会在切换后有二次主键冲突的情况发生。安全的做法是重做主从
问题2: 重启Slave后,自增值追平
从库重启
|
|
从库状态
|
|
我们可以看到,start slave,写入同步正常,mysql会记录auto_increment偏移量,这里是步长是1
|
|
可是,这是由同步发起的auto_increment+1,从时间轴上看,在服务器被重启的时候就已经自动完成上一次落后的追平工作,从库接到的不是一个update操作么,从库重启为什么要进行auto_increment?
答:实际上mysql是通过select max(id)+1 from t的方法来拿到auto_inrement的值
|
|
问题3,插入新数据后,自增值自动追平
主库replace后insert
|
|
从库状态
|
|
实际上mysql也是通过select max(id)+1 from t的方法来拿到auto_inrement的值
以上测试对insert into .. on duplicate key update语句同样效果
|
|
|
|
来看看从库
|
|
竟然也是做了update操作
从这些问题可以看出,MySQL的很多东西,需要我们小白去翻源码。。。
看到资讯阿里和腾讯自己内部的分支都已经修复了这个bug,并将auto_increment值落地,不知道什么时候percona可以参考修正下