写点什么

好险!一入职就遇到 MySQL 这么大 Bug!差点背锅走人!

  • 2021 年 11 月 11 日
  • 本文字数:1208 字

    阅读完需:约 4 分钟

群里一网友这两天刚入职新公司,遇到一个重启 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


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


?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。



场景二




评论

发布
暂无评论
好险!一入职就遇到MySQL这么大Bug!差点背锅走人!