MySQL引發的監控問題
瀏覽量: 次 發布日期:2023-10-11 19:28:35
?MySQL引發的監控問題
一個線上的小案例
微信公眾號:DBA隨筆
今天在線上發現一個問題,挺有意思的,這里簡單記錄下。問題的背景是查看一個Grafana監控的時候,發現監控沒有數據了:
從圖中可以看到4月1日之后,監控就沒有輸出數據了。
于是決定排查一下這個問題。排查思路如下:
1、監控數據源配置是否準確;
2、監控數據是否采集完整;
連云港數據恢復3、監控數據所在數據庫是否可以訪問;
經過查看,監控數據從4月開始就缺失了,由于監控數據采集程序的日志不夠全面,所以花了很長時間才定位到根本原因:監控數據寫入數據庫的時候,報錯了。
其實報錯信息也比較簡單,如下:
這個明眼人一看,就是主鍵沖突了,沖突的id值是4294967295。那就開始排查主鍵沖突的問題吧。1、表結構查看
首先查看表結構,看著似乎沒什么異樣,如下:
2、查看數據
這里找到上面的報出沖突的自增id值,發現是4294967295 ,然后使用select語法來查看這個id對應的數據是否存在:
發現這條數據也在表里面。
于此同時,發現這個表結構里面的auto_increment值也是4294967295
這就比較奇怪了,自增id一般都會是當前表中id最大值的下一個id值,例如表中最大id是10,自增id的值應該是11.
為什么這個自增id和表里面的最大id值一樣?(可能有的小伙伴已經知道答案了,但是排查的時候,我確實沒反應過來)3、數據修復
先嘗試手動delete這條id=4294967295沖突的數據,再重新插入id=4294967295新的數據,看看能不能恢復吧。
結果是:
刪除后重新插入id=4294967295不報錯,但是后續的新數據插入時候又報如下錯誤:
似乎沒解決問題。
既然id=4294967295的數據沖突,那我們把這個id加1,看看手工插入一條數據能不能行:
不得不說,這個輸出的結果有很大的誤導意義
注意,我們插入的數據是id=4294967296,但是報錯還是顯示id=4294967295,死活就跟這條數據過不去了!!!
(這里我以為我發現了什么驚天大bug,喊來兩個同事,一起看看這個問題。)
再次刪除id=4294967295的數據,插入id=4294967296的數據:
我去,沒有了那個壞id的數據,后面的id終于也能插入了???等等,有個warning(同事提醒),看下:
好吧,MySQL已經給出了答案了:id是int 類型的,這個自增值溢出了。
找個測試表試試
到這里,這個問題的原因就算找到了,也能穩定復現這個問題。
使用alter table語句,將這個線上表的主鍵id列改為bigint類型的即可。
測試環境看一發:
從結果中不難看出來,這個操作不能online,會拷貝表里面所有的數據。
線上重要表的操作最好使用pt-osc工具或者gh-ost工具執行。
這里再給一個不同類型的id范圍的表:
說實話,這些范圍邊緣數據,平時不注意的話,看到了可能也反應不過來,如果你夠細心,對它們很敏感,可能這個問題一分鐘就解決了,根本不需要排查。
最終,監控數據也回來了。
修復前:
修復后:
上述情況是在MySQL 5.5 版本上操作的,MySQL8.0中會不會有所改善。
看來MySQL8.0對于這種情況,支持的友好一點。
當表里面有最大id的情況下,插入一個更大的id:MySQL5.5會報最大的id沖突,有一定的誤導;MySQL8.0直接報錯,更嚴謹;
當表里沒有最大id值,但是自增id為最大id值,插入一個更大的id,MySQL5.5會插入成功,但是發生數據截斷,提示warning;MySQL8.0會直接報錯,更嚴謹。
綜上,升級MySQL8.0吧。
今天就這么多,睡覺了。