1. 程式人生 > >記一次MySQL中Waiting for table metadata lock的解決方法

記一次MySQL中Waiting for table metadata lock的解決方法

最近專案中的資料庫查詢經常掛起,應用程式啟動後也報操作超時。測試人員就說資料庫又掛了(貌似他們眼中的連線失敗,查詢無果都是掛了),通過 show processlist 一看,滿屏都是 Waiting for table metadata lock 狀態的連線。第一反應就是kill掉這些連線,奈何連線實在太多,實在kill不過來,於是重啟服務,貌似重啟果真能解決90%的問題,但如果不找到問題原因,問題也肯定會再次出現。

在網上查詢得知MySQL在進行一些alter table等DDL操作時,如果該表上有未提交的事務則會出現 Waiting for table metadata lock ,而一旦出現metadata lock,該表上的後續操作都會被阻塞(詳見

http://www.bubuko.com/infodetail-1151112.html)。所以這個問題需從兩方面解決:

1. 檢視未提交事務

從 information_schema.innodb_trx 表中檢視當前未提交的事務

select trx_state, trx_started, trx_mysql_thread_id, trx_query from information_schema.innodb_trx\G

(\G作為結束符時,MySQL Client會把結果以列模式展示,對於列比較長的表,展示更直觀)

欄位意義:

  • trx_state: 事務狀態,一般為RUNNING
  • trx_started: 事務執行的起始時間,若時間較長,則要分析該事務是否合理
  • trx_mysql_thread_id: MySQL的執行緒ID,用於kill
  • trx_query: 事務中的sql

一般只要kill掉這些執行緒,DDL操作就不會Waiting for table metadata lock。

2. 調整鎖超時閾值

set session lock_wait_timeout = 1800;
set global lock_wait_timeout = 1800;

好讓出現該問題時快速故障(failfast)