MariaDB InnoDB表:如何查找导致"等待表元数据锁定的语句"

时间:2016-08-29 21:31:23

标签: mariadb

如何确定在MariaDB上的元数据锁信息行(SELECT * FROM information_schema.metadata_lock_info)中显示的线程ID的SQL语句是什么?

Server version: 10.0.15-MariaDB MariaDB Server

所有相关问题都涉及"等待表格元数据锁定"从MySQL的角度来看,但这对MariaDB没有帮助,因为它们的内省实现方式与我所说的不同。谷歌搜索并没有发现很多。

A"显示完整的流程清单"给出如下行:

| 57295 | main  | localhost | joints | Execute |   50 | Waiting for table metadata lock | select ...

该声明应该做什么,但不表明它也有锁定。所以,我打开了元数据锁定信息,如[0]所述。这只提供了锁持有者的线程ID,但没有提供语句:

MariaDB [joints]> SELECT * FROM information_schema.metadata_lock_info;
+-----------+--------------------------+-----------------+----------------------+--------------+----------------+
| THREAD_ID | LOCK_MODE                | LOCK_DURATION   | LOCK_TYPE            | TABLE_SCHEMA | TABLE_NAME     |
+-----------+--------------------------+-----------------+----------------------+--------------+----------------+
|     57322 | MDL_INTENTION_EXCLUSIVE  | MDL_EXPLICIT    | Global read lock     |              |                |
|     57322 | MDL_SHARED_NO_READ_WRITE | MDL_EXPLICIT    | Table metadata lock  | joints       | 16_study       |
|     57322 | MDL_INTENTION_EXCLUSIVE  | MDL_EXPLICIT    | Schema metadata lock | joints       |                |
|     57269 | MDL_SHARED_READ          | MDL_TRANSACTION | Table metadata lock  | joints       | authentication |
|     57301 | MDL_SHARED_READ          | MDL_TRANSACTION | Table metadata lock  | joints       | authentication |
|     57280 | MDL_SHARED_READ          | MDL_TRANSACTION | Table metadata lock  | joints       | authentication |
|     57317 | MDL_SHARED_READ          | MDL_TRANSACTION | Table metadata lock  | joints       | ship           |
|     57271 | MDL_SHARED_READ          | MDL_TRANSACTION | Table metadata lock  | joints       | administration |
|     57264 | MDL_SHARED_READ          | MDL_TRANSACTION | Table metadata lock  | joints       | server         |
+-----------+--------------------------+-----------------+----------------------+--------------+----------------+

我真正想要的是看到"加入"锁定发生时的两个输出我没有看到从这两个表中加入数据的方法"因为前者似乎不是一张桌子。我想避免得到:

ERROR 1933 (HY000): Target is not running an EXPLAINable command

在尝试实时执行时,由于线程在被检查时结束。

[0] https://mariadb.com/kb/en/mariadb/metadata_lock_info/

1 个答案:

答案 0 :(得分:1)

THREAD_ID映射到information_schema.PROCESSLIST.IDshow [full] processlist;中的第一列。即:

SELECT * FROM information_schema.METADATA_LOCK_INFO AS mli
JOIN information_schema.PROCESSLIST AS pl ON mli.THREAD_ID = pl.ID

我倾向于以下内容,以便更轻松地了解正在发生的事情(尽管换行符不适用于cli):

SELECT
  mli.THREAD_ID, mli.LOCK_MODE, mli.LOCK_TYPE, 
  CAST(GROUP_CONCAT(DISTINCT CONCAT(mli.TABLE_SCHEMA, '.', mli.TABLE_NAME) ORDER BY mli.TABLE_SCHEMA, mli.TABLE_NAME SEPARATOR '\n') AS CHAR) AS locked_tables, 
  pl.USER, pl.HOST, pl.DB, pl.COMMAND, pl.TIME, pl.STATE, pl.INFO, pl.QUERY_ID, pl.TID
FROM information_schema.METADATA_LOCK_INFO AS mli
JOIN information_schema.PROCESSLIST AS pl ON mli.THREAD_ID = pl.ID
GROUP BY mli.THREAD_ID, mli.LOCK_MODE, mli.LOCK_TYPE
ORDER BY time DESC, pl.ID;

特别有趣的是,当pl.COMMAND = 'Sleep'表示某些连接池或其他(大多数是只读的)程序正在持有已被锁定的打开的连接时。