問題
今天做測試遇到一個問題,在服務(wù)往DB插入數(shù)據(jù)時,出現(xiàn)插入失敗崩溪,發(fā)現(xiàn)報1467的錯誤。
將日志打印的插入SQL到命令行直接執(zhí)行斩松,同樣提示1467錯誤伶唯,并有了更詳細(xì)的說明:
ERROR 1467 (HY000): Failed to read auto-increment value from storage engine
分析
這個報錯看起來是跟自增字段有關(guān)。
查資料后了解到惧盹,其原因是自增字段的數(shù)值已經(jīng)超過了字段類型能夠容納的范圍乳幸。
也就是說,自增字段的類型對應(yīng)一個數(shù)值范圍钧椰,當(dāng)自增ID增長到一定值的時候粹断,會超出范圍,此時就會導(dǎo)致自增ID字段自增失敗了嫡霞。
通過以下語句看一下當(dāng)前自增ID的類型范圍和當(dāng)前自增ID增長到了多少:
> show create table T_XX;
CREATE TABLE `T_XX` (
`FId` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
……
) ENGINE=InnoDB AUTO_INCREMENT=18446744073 DEFAULT CHARSET=utf8
可見當(dāng)前的自增主鍵的范圍是11位無符號整型瓶埋,而最后的AUTO_INCREMENT的值其實就是記錄當(dāng)前表中最大的自增主鍵的值是多少,可以看到已經(jīng)達(dá)到了11位,無法繼續(xù)增加悬赏,才會報錯狡汉。
了解原因后,就可以對癥下藥闽颇。
解決
這里可以有兩個思路:
- 如果ID是正常增長到極限盾戴,此時需要調(diào)大自增ID的范圍
- 如果ID是異常出現(xiàn)了部分新的極大ID,導(dǎo)致無法繼續(xù)增長兵多,此時可以刪去異常記錄尖啡,調(diào)整表的自增ID游標(biāo)。
思路1
有可能隨著測試操作剩膘,ID就是增長到了極限衅斩,此時不好刪數(shù)據(jù),只能調(diào)大自增ID的范圍怠褐。
可以通過以下語句來修改自增主鍵的類型范圍:
ALTER TABLE T_XX MODIFY `FId` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增主鍵';
此時再查看建表語句就會發(fā)現(xiàn)自增ID的范圍已經(jīng)增大了:
> show create table T_XX;
CREATE TABLE `T_XX` (
`FId` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
……
) ENGINE=InnoDB AUTO_INCREMENT=18446744073 DEFAULT CHARSET=utf8
思路2
有時僅僅是因為一些異常情況導(dǎo)致出現(xiàn)幾條極大的自增ID值的記錄畏梆,此時可以刪去它們,然后將當(dāng)前的自增主鍵游標(biāo)修改即可奈懒。
先查看數(shù)據(jù)奠涌,刪去異常的ID的記錄。
然后查到正常增長到的ID磷杏,假設(shè)是12666溜畅,執(zhí)行以下語句:
ALTER TABLE T_XX AUTO_INCREMENT = 12666;
此時再查看建表語句,就會發(fā)現(xiàn)已經(jīng)恢復(fù)了游標(biāo)极祸,可以繼續(xù)插入了:
> show create table T_XX;
CREATE TABLE `T_XX` (
`FId` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
……
) ENGINE=InnoDB AUTO_INCREMENT=12666 DEFAULT CHARSET=utf8
關(guān)注我的公眾號【月亮與二進(jìn)制】慈格,鵝廠程序員的敲碼間隙,也能讀書觀影練劍寫字遥金,分享給你我的世界