事件描述
环境 mysql 8.0.24
在对同步数据的检查时发现了
ID
异常,明明数据只有几百条但是ID却到了几千几万第一反应就是同步的SQL有问题
- 一开始sql考虑了
on duplicate key update
和replace into
,但是由于replace into
会做删除在新增的操作导致无限消耗自增ID ,所以最中选择了on duplicate key update
,但是目前来看on duplicate key update
这个也有问题😫
- 一开始sql考虑了
- 通过测试发现真有问题,insert错误时在进行更新会出现
Affected rows: 2
,也不指定怎么回事,最后看到个博文跟我的情况一模一样 原来是
**MySQL innodb_autoinc_lock_mode **
的问题INSERT … ON DUPLICATE KEY UPDATE …对主键的影响 会出现自增字段突然跳跃式增长的问题
- select @@innodb_autoinc_lock_mode;
- 关于MySQL innodb_autoinc_lock_mode介绍
- MySQL文档
处理
修改
MySQL innodb_autoinc_lock_mode
- 编辑/etc/my.cnf
- [mysqld] 加入如下行: innodb_autoinc_lock_mode=0
- 数据处理完之后 先删除 表 ID, 在新增 表ID
ALTER TABLE test_on_duplicate_key_update DROP
id;
ALTER TABLE test_on_duplicate_key_update ADD
idmediumint(11) PRIMARY KEY NOT NULL AUTO_INCREMENT FIRST;
- 这个博主给出的建议
- 修改业务逻辑
- 修改业务逻辑,将INSERT … ON DUPLICATE KEY UPDATE …语句拆开,先去查询,然后去更新,这样就可以保证主键不会不受控制的增大,但增加了复杂性,原来的一次请求可能变为两次,先查询有没有,然后去更新。
- 删除表的自增主键
- 删除自增主键,让唯一索引来做主键,这样子基本不用做什么变动,只要确定目前的自增主键没有实际的用处即可,这样的话,插入删除的时候可能会影响效率,但对于查询多的情况来说,小A比较两种之后更愿意选择后者。
- 修改业务逻辑