一张会员表
添加5条记录
查看自增id为6
情形一:将数据全部删除,不重启数据库的情况下,新添加3条新数据,看看效果
注:可以看到自增主键不会覆盖之前的主键id,而是出现断层的效果;
情形二:将数据全部删除,重启数据库的情况下,再添加3条新数据,看看效果
注:可以看到旧数据如果全部删除了,再重启数据库,自增主键将被重置为初始状态,新添加的数据就从初始化开始计数了
情形三:表中有5条记录, 我只删除其中id为4,5的两条记录, 不重启数据库,然后再次添加2条新记录,看看效果
开始删除了哈
然后再次添加2条数据
注:可以看到自增主键不会覆盖,而是出现断层情况
情形四:表中有8条记录, 我只删除其中id为7,8的两条记录,重启数据库,然后再次添加3条新记录,看看效果
操作:
- 删除。。。
- 重启。。。
- 添加。。。
结果:
注:可以看到id会自动填充之前的主键id7,8
情形五:表中有8条记录, 我删除前7条记录,保留最后一条记录,看看重启与不重启数据库后新添加2条记录会是什么?
前8条数据
操作:
- 删除。。。
- 不重启。。。
-
添加。。。
结果:
操作:
- 删除。。。
- 重启。。。
-
添加。。。
结果:
注:只要保证最大的一个id不删除,数据库重启不重启,对于新添加的数据都是没有影响的,还是会延续最大的id然后继续走下去
总结:这就是自增主键没有持久化的bug。究其原因,在于自增主键的分配,是由InnoDB数据字典内部一个计数器来决定的,而该计数器只在内存中维护,并不会持久化到磁盘中。当数据库重启时,该计数器会通过下面这种方式初始化。
SELECT MAX(ai_col) FROM table_name FOR UPDATE;