Mysql 自增主鍵回溯的坑
阿新 • • 發佈:2021-07-08
使用mysql的時候,很多時候用自增主鍵。正常使用一般是沒有問題的,但是極小概率情況下會碰到主鍵回溯的問題。在業務上可能造成id一樣,但是對應的業務資料不一樣的問題。這個問題發生在Mysql 8.0版本之前。
出現場景: 插入一條資料返回主鍵3, 接著刪除了主鍵為3的資料,這個時候突然資料庫宕機了,重啟之後再進行插入,返回的主鍵還是3。正常這個時候應該是返回主鍵4的,與預期不一致,對業務資料會造成不一致。
模擬場景:
1、建一張表:
mysql> CREATE TABLE t ( -> a INT AUTO_INCREMENT PRIMARY KEY, -> b VARCHAR(255) default null -> ); Query OK, 0 rows affected (0.03 sec)
2, 插入資料:
mysql> insert into t(`b`) values ('xxx'),('yyy'),('zzz');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
3, 檢視插入的資料
mysql> select * from t;
+---+------+
| a | b |
+---+------+
| 1 | xxx |
| 2 | yyy |
| 3 | zzz |
+---+------+
3 rows in set (0.00 sec)
4, 刪除主鍵為3的資料
mysql> delete from t where a=3;
Query OK, 1 row affected (0.01 sec)
5,這個時候如果直接插入資料,返回的主鍵是4,這是正常的行為。但是如果這個時候突然宕機了,重啟再插入資料,返回的主鍵還是3。這裡只模擬異常情況,將mysql伺服器重啟,然後再插入資料。
mysql> insert into t (`b`) values ('new_line'); Query OK, 1 row affected (0.00 sec) mysql> select * from t; +---+----------+ | a | b | +---+----------+ | 1 | xxx | | 2 | yyy | | 3 | new_line | +---+----------+ 3 rows in set (0.00 sec)
6、可以看到剛插入的資料,主鍵還是3。
原因解釋: MySQL 8.0 版本前,自增不持久化,資料庫重啟時會發生主鍵回溯。
解決方法:
- 升級 MySQL 版本到 8.0 版本,每張表的自增值會持久化;
- 若無法升級資料庫版本,則強烈不推薦在核心業務表中使用自增資料型別做主鍵。
造成影響:如果前端插入一條user的資料,返回給前端一個id,這個時候如果有客戶端刪除了這個id對應的資料,剛好宕機,重啟後又插入一條新的user資料,那麼會覆蓋掉之前的user。這是非常嚴重的業務資料錯亂,造成生產事故的。