我們知道m(xù)ysql的默認隔離級別是RR, 在5.5之前這個隔離級別隔離的數(shù)據(jù)是有問題的, 存在狀態(tài)為running的trx時, mysql期間再執(zhí)行DDL, 就不能保證RR隔離級別的數(shù)據(jù)準確性
mysql為了解決這一問題, 在5.5之后出現(xiàn)了MDL, 這是一個隱式的鎖, 事務(wù)執(zhí)行完后會自動釋放該鎖, 當有DDL執(zhí)行時, 該線程將會被阻塞, 直到所有的線程全部被執(zhí)行完后再執(zhí)行DDL操作
線上問題
線上的測試服務(wù)器啟動起來后, 整個服務(wù)是假死的狀態(tài), 服務(wù)完全不能使用, 排查了服務(wù)器一切都是正常的, 但是mysql數(shù)據(jù)庫發(fā)現(xiàn)很多線程被阻塞等待MDL, 看來是這個服務(wù)器啟動不起來了又反復(fù)啟動幾次服務(wù)
發(fā)現(xiàn)mysql存在線程正在等待該鎖, 由此推斷應(yīng)該存在至少一個正在running的事務(wù), 同時期應(yīng)該也不會存在死鎖或者被鎖住的表的情況, 如下圖所示
解決方案
- 設(shè)置MDL等待超時時間, set session lock_wait_timeout=60
- 查看當前事務(wù), 殺掉事務(wù)線程, 如果當前事務(wù)比較多業(yè)務(wù)比較復(fù)雜, 不建議該操作, 可能引起系統(tǒng)雪崩或者大范圍業(yè)務(wù)回滾
- 選擇mysql相對空閑的時間進行DDL操作, 建議DDL操作不能太頻繁, 明顯不正確的DDL就不要反復(fù)執(zhí)行了