找出未提交的MySQL執行緒/事務

  • 2019 年 10 月 5 日
  • 筆記

找出未提交的MySQL執行緒/事務:

SELECT * from information_schema.processlist;   這個能看到上面哪個SQL執行緒ID(下圖的378號執行緒就是造成MDL鎖的罪魁禍首)

SELECT trx_id,trx_state,trx_started,trx_mysql_thread_id,CURRENT_TIMESTAMP – trx_started AS RUN_TIME from information_schema.innodb_trx;

然後 kill 掉378 執行緒即可。

補充:

場景三:

通過show processlist看不到TableA上有任何操作,在information_schema.innodb_trx中也沒有任何進行中的事務。這很可能是因為在一個顯式的事務中,對TableA進行了一個失敗的操作(比如查詢了一個不存在的欄位),這時事務沒有開始,但是失敗語句獲取到的鎖依然有效,沒有釋放。從performance_schema.events_statements_current表中可以查到失敗的語句。

官方手冊上對此的說明如下:

If the server acquires metadata locks for a statement that is syntactically valid but fails during execution, it does not release the locks early. Lock release is still deferred to the end of the transaction because the failed statement is written to the binary log and the locks protect log consistency.

也就是說除了語法錯誤,其他錯誤語句獲取到的鎖在這個事務提交或回滾之前,仍然不會釋放掉。because the failed statement is written to the binary log and the locks protect log consistency 但是解釋這一行為的原因很難理解,因為錯誤的語句根本不會被記錄到二進位日誌。

處理方法:通過performance_schema.events_statements_current找到其sid, kill 掉該session. 也可以 kill 掉DDL所在的session.