MYSQL 怎麼發現處理沒有commit 留下的「大」麻煩?

  • 2019 年 12 月 17 日
  • 筆記

其實使用不同的資料庫開發應用程式,本身沒有什麼,但開發人員如果不熟悉所使用的資料庫,還沿用自己熟悉資料庫的處理方式來處理新的資料庫,那顯然就會造成很多麻煩,這點對其他職業也是一樣。

今天想說的是,習慣使用ORACLE 的程式設計師,在MYSQL 留下的麻煩怎麼被發現。這兩種資料庫在處理事務上是有不同的,oracle 默認不會自動commit, 而mysql 會默認 auto commit, 說道auto commit ,四大資料庫,只有oracle 一家是不默認commit。

那問題出在哪裡,如果當初在程式設計師使用mysql 上設置了 auto commit 為非自動(執行緒級別,或global),而後期某些原因,又忘記了,記得MYSQL 本身是默認是 auto commit 那亂子就來了。所以一般都會看看developer 的歷史,如果開發的歷史用沒有使用過mysql 則必然會多留心。

下面有一個例子,系統有一個更新一直過不去,一直報

Lock wait timeout exceeded; try restarting transaction

哪遇到這樣的問題,會想起什麼,怎麼處理這個問題。 第一個想法是看看

show engine innodb stauts

看到上面的圖,的反映是什麼,有執行緒霸佔某些記錄的row lock 太長時間了,造成其他的session無法操作對應的記錄。 在往深裡面想,就有可能是沒有commit 而造成的 session idel 而事務running 的問題。

遇到這樣的問題,需要找出當前那個 session 正在idel 但其實裡面的 transaction 在running 的狀態。

1 找到正在sleep的session

2 查看耗時較長的session中運行的語句

通過查看到較長耗時的語句,以及語句的 processlist_id 就可以大致找到當前在作妖的執行緒ID。

然後kill他就好。

當然還有另外一種情況,就是程式裡面由於不嚴謹,導致大批量的begin 但沒有commit, 那這樣用上面的方法就不趕趟了,怎麼來更快的發現這樣的問題

通過上圖的語句,去發現相關的計數器是否一致在瘋狂的上漲,那就證明當前的資料庫系統中存在或可能存在這樣的問題。