調研環境下,對一張千萬條數據的表作了一個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 先記錄的是刪除表的操做,從庫執行的順序就不對了。