mysql replace into 生成全局唯一id遇到AUTO_INCREMENT回退的问题

一、背景

前两天,有同事反馈,调用我们这边的获取全局唯一ID的接口,得到了重复的id。

二、问题跟踪

查看接口日志,发现出现正确返回前,id是五万多,出问题的后,id突然下降到了301。两条相邻的日志如下:

Apr 20, 2022 @ 14:16:52.824

Apr 20, 2022 @ 14:28:01.198

这样看来,是在下午14:28, 生成的id就出现了异常,比上一个id差距非常大。

查看接口逻辑,是通过replace into 一直修改表里的一条记录,实现生成唯一id的逻辑,具体如下。

 replace into的特性如下:

1、replace根据UNIQUE约束的字段(设置为Primary Key),确定被替换的是哪一条记录。如果不存在要替换的记录, 那么就会插入一条新的记录。

2、replace语句会删除原有的一条记录, 并且插入一条新的记录来替换原记录。

 再结合接口传参,sep一直传的是个定死的参数,且有唯一索引,那么接口是通过replace into来实现表里一直只存了一条记录,并且主键id会自增。 那么为啥出问题了呢?

由于以前从来没有使用过replace into, 直接在度娘查了下“replace into出现auto_increment回退”, 刚好看到这位大神的文章,跟我们的现象基本一模一样:INSERT ON DUPLICATE KEY UPDATE与 REPLACE 语句简介 | 五块的博客

 从这位大神的经验,说是由于主从库切换直接引起这个问题,切换到从库的时候,从库的auto_increment同主库的不一致。

和DBA沟通后,确认我们当天下午14:19左右,腾讯云对此数据库进行了主从切换。

那么切换后,为啥会存在auto_increment不一致呢?我们来一起建个表看看

1、建表

2、插入一条数据,此时

 

此时的auto_increment: 

 3、执行 replace into pqj_text values(null,'a');

查看其auto_increment: 

可以看到加1

如果从库更新时,也是执行replace into的话, auto_increment肯定和主库一模一样,但是现在出现了差异,那么从库执行的sql是咋样的呢? 找到DBA给出binglog,发现是update,那么从库是执行的update语句。(下图binlog是引用的别的博主截图)

 

 那么我们试试,直接执行update 语句,会更新auto_increment吗?

4、执行update

在刚刚的测试基础上,执行以下sql

update pqj_text
set id= 10
where sep='a'

再来查看其auto_increment: 

 结果还是3!!没有增加。那么就能看出问题所在了。

当主库执行replace into ,主库的auto_increment一直在增加。

从库通过binlog里的update语句,一直在更新主键id, 但是auto_increment没有改变。

当主从切换后,会从以前的从库auto_incremant自增,导致生成了以前已经出现过的id!!!

三、解决办法

(未完待续)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值