好险!一入职就遇到 MySQL 这么大 Bug!差点背锅走人!
群里一网友这两天刚入职新公司,遇到一个重启 MySQL 服务后,自动增长值丢失问题,差点背锅走人。下面我们一起来回顾一下这个问题。
在 mysql 中用自增列作为主键时,先往表里插入 5 条数据,此时表里数据 id 为 1、2、3、4、5,如果此时删除 id=4、5 的数据后,再重启数据库,重启成功后向表里 insert 数据的时候,INNODB、MyISAM 引擎下 ID 分别是从几开始增加?如果你没经历过,或者当面试时被问到这个问题时,相信多数人都是一脸懵逼。MD 谁有事没事去重启线上数据库嘛。最主要的是很多没有测试过这个场景,没有这方面的经验,我在这里做个笔记,大家轻点喷!
MySQL 通常使用的引擎都是 INNODB,在建表时,一般使用自增列作为表的主键,这样的表对提高性能有一定的帮助。但是自增列有一个坑,并且这个坑存在了很久,一直到 MySQL 8.0 版本,才修复了这个坑,这个坑就是表的自增列变量 auto_increment 在 MySQL 重启后,有可能丢失。
「innodb 引擎(低版本):Innodb 表中把自增列作为主键 ID 时,自增列是通过 auto-increment 计数器实现的,计数器的最大值是记录到内存中的,重启数据库后,会导致 auto-increment 计数器重置,从而会导致主键 ID 重置。」
「MyISam 引擎:MyISAM 表会把自增列(auto-increment 计数器)最大值是记录到数据文件里,重启 MySQL 自增列(计数器)最大值不会丢失,从而使用自增列作为主键 ID 时也不会丢失。」
innodb 主键重置问题
在 MySQL 低版本中,InnoDB 表中使用自增的 auto-increment 计数器 会把值存放在内存中,不会写入磁盘。一旦 MySQL 服务重启,这个值就丢了,InnoDB 引擎会根据表中现有的数据重新计算该计数器的值:获取表中最大的自增主键 ID 作为 auto-increment 计数器的最大计数,当 insert 数据时,在 auto-increment 计数器最大值上 1。
先创建一张 user 表,新增几条数据:
//1.创建 user 表:自增列作为主键 ID
CREATE?TABLE?`user`?(
`id`?int(11)?unsigned?NOT?NULL?AUTO_INCREMENT,
`name`?varchar(255)?NOT?NULL
?DEFAULT?'',
`age`?int(4)?unsigned?NOT?NULL?DEFAULT?'0',
PRIMARY?KEY?(`id`)
)?ENGINE=InnoDB?AUTO_INCREMENT=1?DEFAULT?CHARSET=utf8;
//2.插入 5 条数据
INSERT?INTO?`user`(`name`,?age)?VALUES('刘备 1',?21);
INSERT?INTO?`user`(`name`,?age)?VALUES('刘备 2',?22);
INSERT?INTO?`user`(`name`,?age)?VALUES('刘备 3',?23);
INSERT?INTO?`user`(`name`,?age)?VALUES('刘备 4',?24);
INSERT?INTO?`user`(`name`,?age)?VALUES('刘备 5',?25);
场景一
「mysql 数据库不重启时,innodb 自增主键 ID 会根据 auto-increment 计数器一直递增。」
向 user 表里插入 5 条数据,主键 ID 按自增列通过 auto-increment 计数器实现自增。
在 user 表里删除 id 为 4、5 的数据,再向 user 表中插入一条数据,主键 ID 是 auto-increment 的值 6。
场景二
评论