MySQL服务重启后,MySQL 5.7 InnoDB AUTO

    技术2022-07-10  133

    几天前,系统在重启后,bug频出,发现是新增时主键冲突,很奇怪的现象,最后发现原来是mysql的“bug”,在MySQL 5.7和更早版本中,当重新启动MySQL服务时,每个表上的AUTO_INCREMENT值将重新初始化为:MAX(id)+ 1

    下面是个小测试:

    1. 先创建一个AUTO_INCREMENT_TEST表

    CREATE TABLE `AUTO_INCREMENT_TEST` ( `id` int(20) NOT NULL AUTO_INCREMENT, `name` varchar(200) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1815 DEFAULT CHARSET=utf8;

          这时设置的AUTO_INCREMENT为1815,

    2.然后新增一条主键为 1 的数据:

    INSERT IGNORE INTO `AUTO_INCREMENT_TEST` VALUES (1,'aaa');

    查看自增主键,依旧为1815

     3. 重启mysql服务

       

    查看 AUTO_INCREMENT_TEST表中的AUTO_INCREMENT已经变为了 2.

     

     问题在于,MySQL服务重启后,表上的AUTO_INCREMENT值被重新初始化为 MAX(id)+ 1。但是,当我的项目中在创建时的自增主键是1815,我后期在写insert语句是,可能会手写id为 1815以后的id,  而mysql重启后AUTO_INCREMENT回退了,当自增到我手写的id时,就会发生主键冲突。

    根据MySQL文档,此行为在MySQL 5.8中已更改。显然,AUTO_INCREMENT计数器值将被写入重做日志,以便它们将在服务重启后持续存在。但是,即使进行了5.8更改,MySQL仍警告说仍然存在无法保证的极端情况:

    However, in the case of a server crash, reuse of a previously allocated auto-increment value cannot be guaranteed. Each time the current maximum auto-increment value is changed due to an INSERT or UPDATE operation, the new value is written to the redo log, but if the crash occurs before the redo log is flushed to disk, the previously allocated value could be reused when the auto-increment counter is initialized after the server is restarted.

    Processed: 0.011, SQL: 9