MySQL服務重啓後,MySQL 5.7 InnoDB AUTO_INCREMENT計數器被重置

幾天前,系統在重啓後,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.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章