MariaDB InnoDB table:如何找到导致 "waiting for table metadata lock" 的语句
MariaDB InnoDB table: how to find statement causing "waiting for table metadata lock"
如何确定 MariaDB 上元数据锁定信息行 (SELECT * FROM information_schema.metadata_lock_info) 中显示的线程 ID 的 SQL 语句是什么?
Server version: 10.0.15-MariaDB MariaDB Server
所有相关问题都从 MySQL 的角度深入到“等待 table 元数据锁定”,但这对 MariaDB 没有帮助,因为它们的内省实现方式与我所能实现的不同告诉。谷歌搜索并没有出现很多。
“显示完整进程列表”给出的行如下:
| 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 |
+-----------+--------------------------+-----------------+----------------------+--------------+----------------+
我真正想要的是在发生锁定时看到这两个输出的“连接”。我看不到从这两个“table”中加入数据的方法,因为前者似乎不是 table。我想避免得到:
ERROR 1933 (HY000): Target is not running an EXPLAINable command
尝试实时执行时,由于线程在检查时结束。
THREAD_ID
映射到 information_schema.PROCESSLIST.ID
(show
[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'
,因为这表明某些连接池或其他(主要是只读的)程序正在持有打开的连接,这些连接上有锁。
如何确定 MariaDB 上元数据锁定信息行 (SELECT * FROM information_schema.metadata_lock_info) 中显示的线程 ID 的 SQL 语句是什么?
Server version: 10.0.15-MariaDB MariaDB Server
所有相关问题都从 MySQL 的角度深入到“等待 table 元数据锁定”,但这对 MariaDB 没有帮助,因为它们的内省实现方式与我所能实现的不同告诉。谷歌搜索并没有出现很多。
“显示完整进程列表”给出的行如下:
| 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 |
+-----------+--------------------------+-----------------+----------------------+--------------+----------------+
我真正想要的是在发生锁定时看到这两个输出的“连接”。我看不到从这两个“table”中加入数据的方法,因为前者似乎不是 table。我想避免得到:
ERROR 1933 (HY000): Target is not running an EXPLAINable command
尝试实时执行时,由于线程在检查时结束。
THREAD_ID
映射到 information_schema.PROCESSLIST.ID
(show
[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'
,因为这表明某些连接池或其他(主要是只读的)程序正在持有打开的连接,这些连接上有锁。