truncate被Waiting for table metadata lock的解決方法

場景

調研環境下,對一張千萬條數據的表作了一個truncate操做,發現長時間無反應。mysql

解決思路

操做一直執行,決定查詢下正在執行的sql的狀態sql

shop processlist;

發現truncate操做的狀態是:Waiting for table metadata lock。bash

查詢正在執行的事務:spa

select * from information_schema.innodb_trx\G

找到了操做表的那個事務,有insert語句沒有提交,查看事務的trx_mysql_thread_id,而後執行kill [id]刪除。設計

卡住的sql就都執行成功了。code

思考

MDL是爲了保護database objects而設計的。orm

MDL和事務的關係是,在事務中,當訪問一個database object時都先要得到其MDL,在事務結束後纔會釋放MDL。事務

這樣作有幾個目的:ssl

第一是爲了進一步保證事務的一致性,好比事務A對某一行記錄進行了更新,尚未提交,但這時另一個會話2要修改表名,若是事務 A 持有MDL,那另外一個會話2將沒法修改,show processlist會發現它在Waiting for table metadata lock。直到事務 A 提交或回滾後,才能得到MDL修改爲功。同步

第二是爲了解決 binlog 同步的一個 bug,這個和上面的緣由同樣。binlog 的操做是基於事務的提交順序的。事務 A 還未提交,另外一個會話刪除了相關表,這樣 binlog 先記錄的是刪除表的操做,從庫執行的順序就不對了。

相關文章
相關標籤/搜索