MySQL中的自增主键 ID自增到最大,使用完id会发生什么,怎么办?
Posted Agly_Charlie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL中的自增主键 ID自增到最大,使用完id会发生什么,怎么办?相关的知识,希望对你有一定的参考价值。
文章目录
背景
之前的学习和实践上了解到的是:
SQL插入异常,主键冲突错误,因为自增ID达到上限后,再申请时它的值不会改变,继续插入数据会导致报主键冲突错误
/* SQL Error (1062): Duplicate entry '2147483647' for key 'PRIMARY' */
但我在偶然中发现,还会有这个错误信息,读取自增ID失败。
/* SQL Error (1467): Failed to read auto-increment value from storage engine */
测试过程
于是产生了进一步实验的想法,以下是操作过程:
本次测试环境MySQL 5.7.22
创建表,自增ID
CREATE TABLE `tb_id_incr` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB;
场景一:测试自增ID已经达到最大值
- 第1步:测试,直接让表记录自增ID达到最大值:
INSERT INTO `tb_id_incr` (`id`, `name`) VALUES ('2147483647', '3');
- 第2步:达到最大值后,再insert一条记录
INSERT INTO `tb_id_incr` (`name`) VALUES ('3');
/* SQL Error (1062): Duplicate entry '2147483647' for key 'PRIMARY' */
- 第3步:达到最大值后,再insert 多个记录,
INSERT INTO `tb_id_incr` (`name`) VALUES ('3'),('4'),('5'),('6'),('7'),('8'),('9')
/* SQL Error (1062): Duplicate entry '2147483647' for key 'PRIMARY' */
结论:都产生主键冲突错误
场景二:测试自增ID即将达到最大值
- 第1步:让表记录自增ID 即将达到最大值:
INSERT INTO `tb_id_incr` (`id`, `name`) VALUES ('2147483640', '3');
- 第2步:还没达到最大值后,再insert 多个记录,
INSERT INTO `tb_id_incr` (`name`) VALUES ('3'),('4'),('5'),('6'),('7'),('8'),('9'),('3'),('4'),('5'),('6'),('7'),('8'),('9'),('5'),('6'),('7'),('8'),('9');
/* SQL Error (1467): Failed to read auto-increment value from storage engine */
- 第3步:查看内部自增ID
查看show create table的值已达到最大ID,表明批量插入失败,但还是会继续消耗ID,自增到最大后,报错提示读取自增ID失败
总结
自增ID用完了,会发生两种情况:
- 如果是已经是最大ID了,那么会报错:主键冲突:
/* SQL Error (1062): Duplicate entry '2147483647' for key 'PRIMARY' */
- 如果是即将到达最大值,并且此时批量插入的记录条数大于剩余可用的ID数,会继续消耗ID,自增到最大后,报错提示读取自增ID失败:
/* SQL Error (1467): Failed to read auto-increment value from storage engine */
解决方案
- 一般来说表不应该存在这么大,在达到这么大之前就应该优化,例如,做分库分表之类的优化了。
- 调整数据类型,修改为BIGINT数据类型,但是要注意数据太多,DDL执行时长问题。(参考文末扩展内容)
- 注意上层业务ORM框架的解析也要使用LONG数据类型
扩展
扩展1:修改字段的数据类型,建议使用modify 用法
1.修改字段的数据类型,建议使用modify 用法,更加友好;
modify 和change 区别:参考 https://stackoverflow.com/questions/14767174/modify-column-vs-change-column
# CHANGE
ALTER TABLE
`tb_id_incr`
CHANGE
COLUMN `id` `id` BIGINT NOT NULL AUTO_INCREMENT;
# MODIFY
ALTER TABLE
`tb_id_incr`
MODIFY
COLUMN `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT;
扩展2:Alter table的底层原理
- INPLACE模式和COPY复制临时表模式
https://dev.mysql.com/doc/refman/5.7/en/alter-table.html
- 修改数据类型使用的模式
https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html
可以看到 修改数据类型,只会使用COPY模式
修改过程,是会影响读写。
以上是关于MySQL中的自增主键 ID自增到最大,使用完id会发生什么,怎么办?的主要内容,如果未能解决你的问题,请参考以下文章