資料庫自增id竟然被我用完了

2021-09-26 06:59:49 字數 1372 閱讀 2096

事情的起因是這樣的…幾個月前做過乙個統計型別的job,上線之後小修小補了幾次一直執行的很平穩,就是有乙個缺點:慢。起初我一直以為是因為資料量過大導致的,每天早上六點準時開跑,一般要到下午一兩點才能跑完,其實現在想想這麼長時間的執行肯定是不合理的,而且本身業務的資料量也沒有大到那個地步,但是由於一直工作太忙了(懶),再加上本身不算特別重要的模組就沒有過多在意,但是由於我們的job只有乙個節點,所以如果存在這種長時間執行的job就會導致我們專案的發版時間非常受限制,基本每天只有下午三點到六點左右可以發版,終於我在忍無可忍之後決定重構**,徹底優化。

優化的結果還是十分理想的,現在只需要到七點半就可以跑完了,但是我卻發現了乙個嚴重的問題,快是快了…可是跑完了表裡沒資料啊…

1.我此時第一反應是冷靜,雖然詭異但是肯定是有原因的,首先我們公司的業務肯定遠遠沒有達到這個量級,況且這張統計表是按月分表的,不可能積攢這麼多資料,而且實際檢視後發現只有130w資料而已;

2.資料庫的自增id按理說有bug的概率很小,那麼看來應該還是有問題,此時唯一的辦法就是鑽回**一**竟,好在**我比較熟悉,操作這張表其實只有一句sql,insert into table … on duplicate key update,那看來和這個on duplicate key update逃脫不了干係了;

3.on duplicate key update是指根據表的唯一索引判斷當前資料是插入還是更新,是乙個很方便的語法,否則我們還需要**實現先查詢判斷是否存在,再更新或者插入,不僅**臃腫,而且多了一次io。方便是方便,但是坑也在這裡,因為這句sql不能確定是insert還是update,所以其實每次都會申請出足夠的主鍵id用於插入,由於我的**是批量插入,也就是說假如我一次放入1000條資料,那麼主鍵id會先申請1000個,因為有可能全是insert不存在update,所以導致不管有沒有真的插入主鍵id都自增了,這樣id既不連續,又增長的快…這下明白了,看來問題就出現在這裡,快速增長的id到達了int最大值導致後續資料全部插入失敗;

4.到這裡故事沒有結束,因為其實我心裡還是大概有量級的,21億啊,乙個月就100w+的統計量,這得重複多少次才能夠21億啊,總感覺雖然找到問題了,但是好像還不能完全說通,況且從業務上來講,應該根本沒有多少這種衝突,每次基本都是insert才對,看來事情還是沒有這麼簡單,於是我又鑽入了**中…終於…發現了最sb的事情,我的批處理是用乙個map做的,迴圈map得到資料然後批量插入,但是這個map是乙個方法內的區域性變數,但是定義在了大迴圈的最外層,而迴圈體內沒有任何清除操作…也就是說map是一直在累加的,而由於業務需求,**的迴圈次數是非常多的,所以說第n次總會無效插入前n-1次的累計資料…這麼一算的話量就有點兒可怕…所以也最終導致了主鍵被用完的恐怖情況

1.mysql語法功能實現掌握不足,導致定位問題存在偏差,且編碼時也沒注意;

2.map的問題太低階了!在迴圈裡用容器或者map一定要注意清空!

自增 ID 用完了怎麼辦

引言 在面試中,大家應該經歷過如下場景 面試官 用過mysql吧,你們是用自增主鍵還是uuid?你 用的是自增主鍵 面試官 為什麼是自增主鍵?你 因為採用自增主鍵,資料在物理結構上是順序儲存,效能最好,blabla 面試官 那自增主鍵達到最大值了,用完了怎麼辦?你 what,沒複習啊!然後,你就可以...

面試官 資料庫自增ID用完了會怎麼樣?

看到這個問題,我想起當初玩魔獸世界的時候,25h難度的腦殘吼的血量已經超過了21億,所以那時候副本的boss都設計成了轉階段 回血的模式,因為魔獸的血量是int型,不能超過2 32大小。這些都是題外話,只是告訴你資料量大了是有可能達到上限的而已,回到mysql自增id上限的問題,可以分為兩個方面來說...

資料庫ID自增優缺點?

優點 1.自增,趨勢自增,可作為聚集索引,提公升查詢效率 2.節省磁碟空間。500w資料,uuid佔5.4g,自增id佔2.5g.3.查詢,寫入效率高 查詢略優。寫入效率自增id是uuid的四倍。缺點 1.匯入舊資料時,可能會id重複,導致匯入失敗。2.分布式架構,多個mysql例項可能會導致id重...