TiDb表主键 id AUTO_INCREMENT=1654033,从mysql迁移到TiDb后现在插入数据自动分配的id小于1654033会报 Duplicate entry ‘1573741’ for key ‘PRIMARY’,确定1573741这个id没有值,请问是什么问题,另外如果不建议使用AUTO_INCREMENT,是否可以使用 AUTO_RANDOM(官网不建议生产使用),如果要把表主键key的AUTO_INCREMENT修改AUTO_RANDOM,应该怎么操作。
当前版本是4.0.9,插入数据会轮流插入当前number之前或之后,感觉应该分region了。
1.上面提示 Duplicate entry for key ‘PRIMARY’ ,能否提供下具体的操作记录;
2.使用 auto_increment 主要是容易引起热点问题,可以考虑打开 alter-primary-key
,然后在建表语句上加上 SHARD_ROW_ID_BITS
和 PRE_SPLIT_REGIONS
来避免热点问题;
3.无法直接在表上将 AUTO_INCREMENT 修改为 AUTO_RANDOM,只能重新建表后再灌入数据。
人为向自增列写入值后 TiDB 分配自增值时报 “Duplicate entry” 错误的处理方法
在集群中有多个 tidb-server 时,人为向自增列写入值之后,可能会导致 TiDB 分配自增值冲突而报 “Duplicate entry” 错误:
假设有这样一个带有自增 ID 的表:create table t(id int unique key auto_increment, c int);
TiDB 实现自增 ID 的原理是每个 tidb-server 实例缓存一段 ID 值用于分配(目前会缓存 30000 个 ID),用完这段值再去取下一段。
假设集群中有两个 tidb-server 实例 A 和 B(A 缓存 [1,30000] 的自增 ID,B 缓存 [30001,60000] 的自增 ID),依次执行如下操作:
客户端向 B 插入一条将 id 设置为 1 的语句 insert into t values (1, 1),并执行成功。
客户端向 A 发送 Insert 语句 insert into t © (1),这条语句中没有指定 id 的值,所以会由 A 分配,当前 A 缓存了 [1, 30000] 这段 ID,所以会分配 1 为自增 ID 的值,并把本地计数器加 1。而此时数据库中已经存在 id 为 1 的数据,最终返回 Duplicated Entry 错误。
处理该问题只需要调大表上的 AUTO_INCREMENT 属性值即可让所有 tidb-server 重新获取一段自增 ID:
- 确认表上自增值的最大值:show create table t;
修改表上的自增值最大值到一个更大的值:alter table t AUTO_INCREMENT=120000;
1.正常的插入数据后报Duplicate entry for key ‘PRIMARY’,后端应该自动分了多个region,插入后一段大于当前最大分配至没有问题,后续切换到另外小于当前分配最大值后报错;
2. 请问怎么打开打开 alter-primary-key
。
执行正常的插入报 Duplicate entry,发现实际分配的id在表中确实不存在,之前同事后台手工执行过insert,之前插入的记录应该跟现在新插入记录将分配的id不一样。
1.麻烦提供一下具体的操作过程,方便我们这边排查和复现;
2.打开 alter-primary-key 参考下:https://docs.pingcap.com/zh/tidb/stable/tidb-configuration-file#alter-primary-key
从mysql迁移到TiDb,同事手工后台向表插入一些数据(未指定id)后,前端业务保存业务数据后就报Duplicate entry
麻烦核实下前端业务保存业务数据时有无指定 id 值,若指定了值,则报错可能是上面 3 楼说的原因;若没有指定值,烦请告知下具体集群版本和复现的操作步骤或截图。
此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。