随笔 - 171  文章 - 0  评论 - 0  阅读 - 62083

mysql的主键超过最大值会发生什么?

设置主键的情况下

在自增主键达到int64最大后,再次插入一行记录,报错如下:

Duplicate entry ‘4294967295for key ‘increment_id_test.PRIMARY’

唯一键冲突报错:当auto_incement达到上限后,再次申请下一个id时,得到的值保持不变。

在建表时,通常都会将主键id设置为8字节的bigint unsigned (2^64)。
理论上,在并发够大,时间够长的情况下,还是有可能达到其上限,但到目前为止,还没有一个mysql实例超过这个上限,实际中不会发生。

未设置主键的情况下

如果数据表没有设置主键,那么Innodb会给该表设置一个不可见,长度为6字节的默认主键row_id。
Innodb维护了一个全局的dict_sys.row_id值,它被所有无主键的数据表共同使用。
每个无主键的数据表插入一行数据,都会将当前dict_sys.row_id的值加1。

  1. row_id写入表中的值范围,是从0至2^48-1。
  2. 当row_id的值为2^48时,再进行数据插入,那么row_id的后6个字节的值,就全部为0了。

当row_id的值到了2^48次方-1后,再次插入数据,下一个值是0,然后开始循环。
不过和自定义主键不同的是,row_id标识的主键,没有唯一性约束。
当插入数据的row_id值,在表中已经存在,那么写入的数据会覆盖已存在的数据,且不会报错。

Innodb没有暴露出修改该值的接口和命令。

总结

在设计表时,最好还是使用自定义主键,而不要使用Innodb的默认主键。
至少在自定义主键的场景下,当自增id达到上限时,插入数据,系统会提示报错信息,而不是覆盖数据。
因为数据覆盖意味着数据丢失,影响的是数据可靠性,而插入失败产生的报错,影响是可用性。
在数据业务中,可靠性通常是优先于可用性。

posted on   zhengbiyu  阅读(410)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示