MySQL自增变量auto_increment踩坑,重启后值丢失

转载:https://baijiahao.baidu.com/s?id=1637367920353569708&wfr=spider&for=pc

MySQL在建表时,推荐使用自增列作为表的主键,这样的表在某些场景下,对提高性能有一定的帮助。但是自增列有一个坑,并且这个坑存在了很久,一直到MySQL 8.0版本,才修复了这个坑,这个坑就是表的自增列变量auto_increment在MySQL重启后,有可能丢失。

问题复现(MySQL5.7.19):

1、创建两张表tb1,tb2,tb1为innodb表,tb2为myisam表,建表语句:

create table tb1(id int auto_increment, primary key(id)) engine=innodb;

create table tb2(id int auto_increment, primary key(id)) engine=myisam;

2、分别往tb1,tb2中写5条记录,SQL:

insert into tb1 values(NULL); 重复执行5次

insert into tb2 values(NULL); 重复执行5次

3、通过show create table,查看tb1,tb2的auto_increment都为6。

4、删除tb1,tb2中的所有数据    delete from tb1;      delete from tb2;

5、通过show create table,查看tb1,tb2的auto_increment仍然都为6。

6、重启MySQL

7、通过show create table,查看tb1,tb2的auto_increment。

tb1 innodb表的auto_increment值为1。

tb2 myisam表的auto_increment值仍然为6。

原因分析:

MySQL innodb表的自增变量的值是内存中的临时值,在MySQL重启后就会丢失,MySQL重启时该值以当前表中自增字段的最大值确定下次自增值,比如上表tb1没有数据,重启后auto_increment值默认为1,从1开始自增。如果表tb1有数据,比如id的最大值为4,重启后,auto_increment值将变为5,也就是max(field_value)+1。

MySQL的这个问题,无形中给业务埋下了坑,某些业务依赖自增ID来生成唯一值,当删除一些记录并重启MySQL后,新生成的ID可能与之前的ID有重复,导致ID冲突,因此任何依赖于auto_increment 值的业务逻辑,都需要慎重,要充分了解MySQL auto_increment的实现方式,避免踩坑。

auto_increment值丢失的问题从MySQL 4.0、5.1、5.5、5.6、5.7版本一直存在,终于在MySQL 8.0 解决了,MySQL 8.0版本对auto_increment值进行持久化,MySQL重启后,该值不再丢失。

总结:

MySQL自增变量auto_increment值重启后丢失,只适用于innodb表,myisam表并不会丢失。

MySQL 8.0 修复了auto_increment值重启后丢失的问题。

 

 

### MySQL 8.0.35 中 auto_increment 的初始设置与默认行为 在 MySQL 8.0.35 中,`auto_increment` 的初始可以通过多种方式设置。以下是对 `auto_increment` 初始设置和默认行为的详细说明: #### 1. 创建表时指定初始 当创建表时,可以将 `auto_increment` 的初始作为表选项指定,放置在括号外。例如: ```sql create table t_user2( id int primary key auto_increment, name varchar(20) ) auto_increment=100; ``` 在此示例中,`id` 字段的起始被设置为 100[^1]。 #### 2. 创建表后修改初始 如果表已经创建,但需要更改 `auto_increment` 的初始,可以使用 `ALTER TABLE` 语句。例如: ```sql create table t_user3( id int primary key auto_increment, name varchar(20) ); alter table t_user3 auto_increment = 200; ``` 在此情况下,`t_user3` 表的 `id` 字段从 200 开始自[^1]。 #### 3. `auto_increment_offset` 和 `auto_increment_increment` 的影响 在某些场景下,可以通过系统变量 `auto_increment_offset` 和 `auto_increment_increment` 来控制 `auto_increment` 的行为。例如: ```sql SET @auto_increment_offset = 5; SET @auto_increment_increment = 10; CREATE TABLE autoinc2 ( col INT NOT NULL AUTO_INCREMENT PRIMARY KEY ); INSERT INTO autoinc2 VALUES (NULL), (NULL), (NULL), (NULL); SELECT col FROM autoinc2; ``` 上述代码中,`col` 的将分别为 5、15、25 和 35。这是因为 `auto_increment_offset` 确定了起始,而 `auto_increment_increment` 决定了每次递的步长[^2]。 #### 4. 默认行为 如果没有显式设置 `auto_increment` 的初始,则其默认从 1 开始。此外,`DELETE` 操作不会重置 `auto_increment` 的计数器,而 `TRUNCATE` 操作会将其重置为默认(即 1)。例如: ```sql delete from t_user1; insert into t_user1 values(null,'张三'); -- 自增长从断点开始 truncate t_user1; insert into t_user1(name) values('李四'); -- 自增长从 1 开始 ``` 此行为适用于 MySQL 8.0.35 及之前的版本[^1]。 #### 5. 注意事项 - 在 MySQL 8.0 中,`mysql_install_db` 已被移除,数据字典初始化需要通过带有 `--initialize` 或 `--initialize-insecure` 选项的 `mysqld` 实现[^4]。 - 如果需要跨服务器同步或分片,建议合理配置 `auto_increment_offset` 和 `auto_increment_increment`,以避免主键冲突。 ```sql -- 示例:设置全局变量以避免主键冲突 SET GLOBAL auto_increment_increment = 10; SET GLOBAL auto_increment_offset = 1; ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值