MySQL 5.7中如何定位DDL被阻塞的问题(2)

session3> select * from performance_schema.threads where thread_id in (27,29)\G
*************************** 1. row ***************************
          THREAD_ID: 27
              NAME: thread/sql/one_connection
              TYPE: FOREGROUND
    PROCESSLIST_ID: 2
  PROCESSLIST_USER: root
  PROCESSLIST_HOST: localhost
    PROCESSLIST_DB: NULL
PROCESSLIST_COMMAND: Sleep
  PROCESSLIST_TIME: 214
  PROCESSLIST_STATE: NULL
  PROCESSLIST_INFO: NULL
  PARENT_THREAD_ID: 1
              ROLE: NULL
      INSTRUMENTED: YES
            HISTORY: YES
    CONNECTION_TYPE: Socket
      THREAD_OS_ID: 9800
*************************** 2. row ***************************
          THREAD_ID: 29
              NAME: thread/sql/one_connection
              TYPE: FOREGROUND
    PROCESSLIST_ID: 4
  PROCESSLIST_USER: root
  PROCESSLIST_HOST: localhost
    PROCESSLIST_DB: NULL
PROCESSLIST_COMMAND: Query
  PROCESSLIST_TIME: 172
  PROCESSLIST_STATE: Waiting for table metadata lock
  PROCESSLIST_INFO: alter table slowtech.t1 add c1 int
  PARENT_THREAD_ID: 1
              ROLE: NULL
      INSTRUMENTED: YES
            HISTORY: YES
    CONNECTION_TYPE: Socket
      THREAD_OS_ID: 9907
2 rows in set (0.00 sec)

将这两张表结合,借鉴sys.innodb_lock _waits的输出,实际上我们也可以直观地呈现MDL的等待关系。

SELECT
    a.OBJECT_SCHEMA AS locked_schema,
    a.OBJECT_NAME AS locked_table,
    "Metadata Lock" AS locked_type,
    c.PROCESSLIST_ID AS waiting_processlist_id,
    c.PROCESSLIST_TIME AS waiting_age,
    c.PROCESSLIST_INFO AS waiting_query,
    c.PROCESSLIST_STATE AS waiting_state,
    d.PROCESSLIST_ID AS blocking_processlist_id,
    d.PROCESSLIST_TIME AS blocking_age,
    d.PROCESSLIST_INFO AS blocking_query,
    concat('KILL ', d.PROCESSLIST_ID) AS sql_kill_blocking_connection
FROM
    performance_schema.metadata_locks a
JOIN performance_schema.metadata_locks b ON a.OBJECT_SCHEMA = b.OBJECT_SCHEMA
AND a.OBJECT_NAME = b.OBJECT_NAME
AND a.lock_status = 'PENDING'
AND b.lock_status = 'GRANTED'
AND a.OWNER_THREAD_ID <> b.OWNER_THREAD_ID
AND a.lock_type = 'EXCLUSIVE'
JOIN performance_schema.threads c ON a.OWNER_THREAD_ID = c.THREAD_ID
JOIN performance_schema.threads d ON b.OWNER_THREAD_ID = d.THREAD_ID\G

*************************** 1. row ***************************
              locked_schema: slowtech
                locked_table: t1
                locked_type: Metadata Lock
      waiting_processlist_id: 4
                waiting_age: 259
              waiting_query: alter table slowtech.t1 add c1 int
              waiting_state: Waiting for table metadata lock
    blocking_processlist_id: 2
                blocking_age: 301
              blocking_query: NULL
sql_kill_blocking_connection: KILL 2
1 row in set (0.00 sec)

输出一目了然,DDL操作如果要获得MDL,执行kill 2即可。

官方的sys.schematablelock_waits

实际上,MySQL 5.7在sys库中也集成了类似功能,同样的场景,其输出如下,

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/6786ee6723cc843ac60b64cff81b5ec6.html