自增列持久化
- MySQL5.7以及早期版本中,InnoDB自增列计数器(AUTO _ INCREMENT)的值只存在内存中。
- MySQL8.0每次变化时将自增计数器的最大值写入redo log,同时在每次检查点将其写入引擎私有的系统表。
- 解决了长期以来的自增字段值可能重复的bug。
我们可以重现一下自增列中存在的bug
创建一个测试表
create table t(id int aute - increment primary key,c1 varchar (10));
//他有一个id列,是自增的数字,设为主键,有创建c1为字符
生成一些记录,3条a,b,c
insert into t(c1) values('a'),('b'),(’c‘);
我们来查询这张表
select * from t;
我们再来删除一条记录
delete from t where id=3;
select * from t;
这个时候我们重启一下
我们在来生成一条记录
insert into t(c1) values('d');
select * from t;
这里我们可以看到这个自增列已增长到3,实际上它的id
值应该是4,它有一个重复的id
我们把c1=’a‘的id改成5
update t set id=5 where c1 = 'a';
select * from t;
这个时候再插入一条记录
insert into t(c1) values('e');
select * from t;
我们可以看到id为4,他是基于3接着往上增长的。
如果我们还插入一条记录
insert into t(c1) values('e');
如图所示,它就出现了主键重复的一个问题
对于8.0当中是如何解决这个问题的
与上面相同同样创建一个测试表
先删除一条记录
delect from t where id = 3;
select * from t;
同样退出重启一下
插入一条新的记录
insert into t(c1) values('d');
seolect * from t;
我们可以看到“d”的id不是3而是4,也就是说不会使用以前用过的id,即使把以前的值删掉,或在事务当中使用事务的id进行了事务的回管,他会认为你已经使用过计数器的值,而不会在生成重复的值。
同样:
update t set id=5 where c1 = 'a';
select * from t;
insert into t(c1) values('e')
select * from t;
我们看到它没有出错,而是生成了6,它感知了我们表中对id的修改。
相关参数的变化
show jvariables like 'innodb _ autoinc%';
对于8.0而言它的默认值是2
在5.7当中他的默认值为1.
在8.0当中这个2它代表的是交叉模式,也就是说它这个锁是交叉生成的。
1代表的是连续模式,他的差别在于复制时,可以保证语句级别的id生成自动增长的列时连续的.
网友评论