簡單點說:
以下情況會導致 MySQL 自增主鍵不能連續:
- 唯一主鍵沖突會導致自增主鍵不連續;
- 事務回滾也會導致自增主鍵不連續。
相關面試題總結如下:
一:自增主鍵是連續的么?
- 自增主鍵不能保證連續遞增。
二:自增值保存在哪里?
當使用 show create table `table_name`;時,會看到 自增值,也就是 AUTO_INCREMENT。
CREATE TABLE `t` ( .... ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
這個輸出結果容易引起這樣的誤解:自增值是保存在表結構定義里的。
實際上,表的結構定義存放在后綴名為.frm 的文件中,但是並不會保存自增值。
三:不同的引擎對於自增值的保存策略不同。
1)MyISAM 引擎
- 自增值保存在數據文件中。
2)InnoDB 引擎
保存在了內存里,並且到了 MySQL 8.0 版本后,才有了“自增值持久化”的能力,也就是才實現了“如果發生重啟,表的自增值可以恢復為 MySQL 重啟前的值”。
過程
在 MySQL 5.7 及之前的版本,自增值保存在內存里,並沒有持久化。
每次重啟后,第一次打開表的時候,都會去找自增值的最大值 max(id),然后將 max(id)+1 作為這個表當前的自增值。
舉例來說,如果一個表當前數據行里最大的 id 是 10,AUTO_INCREMENT=11。
這時候,我們刪除 id=10 的行,AUTO_INCREMENT 還是 11。
但如果馬上重啟實例,重啟后這個表的 AUTO_INCREMENT 就會變成 10。
在 MySQL 8.0 版本,將自增值的變更記錄在了 redo log 中,重啟的時候依靠 redo log 恢復重啟之前的值。
四:什么情況會導致自增ID不連續?
1)唯一鍵沖突
執行器對自增鍵+1,但是 innoDB 發現唯一鍵沖突,導致的不連續。
2) 事務回滾
- 事務添加自增鍵+1,但是由於回滾數據,數據被清除,導致的不連續。