在主庫上truncate table後,發現從庫延時開始增加,show processlist可見如下信息。
72105289 system user NULL Connect 2996302 Waiting for master to send event NULL 0 0
72105290 system user dbname Connect 491 Waiting for table metadata lock truncate table tblname 0 0
MySQL用metadata lock控制對於數據庫對象的併發訪問,和保證數據的一致性。MySQL中不能對一個正在使用的表執行DDL語句,就是通過獲取表的metadata lock實現的,其阻止了表結構的變更。即,若表正被一個事務使用,在該事務結束前,另一個會話是不能對此表執行DDL的。
Waiting for table metadata lock,表明在truncate table之前已有事務在使用tblname表了,且該事務還沒結束,從show processlist中看不到進一步的信息了。
但information_schema中的innodb_trx表可以提供正在InnoDB中運行着的事務的信息,如事務是否在等待鎖、事務的開始時間、事務中正在運行的SQL等。
查看innodb_trx表,發現了一個事務,Id爲90916563(trx_mysql_thread_id對應show processlist中的Id),開始時間是2019-02-12 13:26:56,在主庫執行truncate table的時間是17:35,其運行的時間有些異常;另trx_query爲NULL,可判斷該事務很可能卡在這,未正常結束,阻止了truncate table的繼續。
mysql> select * from INNODB_TRX \G
*************************** 1. row ***************************
trx_id: 146633268809
trx_state: RUNNING
trx_started: 2019-02-12 13:26:56
trx_requested_lock_id: NULL
trx_wait_started: NULL
trx_weight: 0
trx_mysql_thread_id: 90916563
trx_query: NULL
trx_operation_state: NULL
trx_tables_in_use: 0
trx_tables_locked: 0
trx_lock_structs: 0
trx_lock_memory_bytes: 1136
trx_rows_locked: 0
trx_rows_modified: 0
trx_concurrency_tickets: 0
trx_isolation_level: REPEATABLE READ
trx_unique_checks: 1
trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
trx_adaptive_hash_latched: 0
trx_adaptive_hash_timeout: 0
trx_is_read_only: 0
trx_autocommit_non_locking: 0
1 row in set (0.00 sec)
從show processlist中看到Id爲90916563線程的信息,其Time爲1294。kill掉該線程,主從複製恢復正常。
90916563 dbname_read 192.168.2.36:63063 dbname Sleep 1294 NULL 100 100
若想查看metadata lock的詳細信息,可藉助Performance Schema下的metadata_locks表。
PS. MySQL的版本是5.7.17-13-log。