显示来自get_lock的所有当前锁
有没有办法select/显示所有使用GET_LOCK
函数取出的当前锁?
请注意, GET_LOCK
锁与表锁不同,就像使用LOCK TABLES
获取的锁一样 – 想要知道如何查看这些锁的读者应该阅读检测locking表(由LOCK TABLElocking)
从MySQL 5.7开始,性能模式公开所有元数据锁,包括与GET_LOCK()
函数相关的锁。
请参阅http://dev.mysql.com/doc/refman/5.7/en/metadata-locks-table.html
SHOW FULL PROCESSLIST;
你会看到那里的锁
从MySQL 5.7开始,这是可能的,但需要先在performance_schema.setup_instruments
表中启用mdl
工具。 您可以通过执行以下操作临时执行此操作(直到下一次重新启动服务器):
UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name = 'wait/lock/metadata/sql/mdl';
或者,通过在my.cnf
文件的[mysqld]
部分添加下面的咒语(或者MySQL在您的安装中读取的任何configuration文件):
[mysqld] performance_schema_instrument = 'wait/lock/metadata/sql/mdl=ON'
(当然,如果你采用后一种方法,MySQL将需要重新启动以使configuration更改生效。)
通过对performance_schema.metadata_locks
表运行SELECT
,可以看到启用mdl
乐器后取出的locking。 如文档中所述, GET_LOCK
锁具有'USER LEVEL LOCK'
的OBJECT_TYPE
,因此我们可以用WHERE
子句将查询过滤到它们:
mysql> SELECT GET_LOCK('foobarbaz', -1); +---------------------------+ | GET_LOCK('foobarbaz', -1) | +---------------------------+ | 1 | +---------------------------+ 1 row in set (0.00 sec) mysql> SELECT * FROM performance_schema.metadata_locks -> WHERE OBJECT_TYPE='USER LEVEL LOCK' -> \G *************************** 1. row *************************** OBJECT_TYPE: USER LEVEL LOCK OBJECT_SCHEMA: NULL OBJECT_NAME: foobarbaz OBJECT_INSTANCE_BEGIN: 139872119610944 LOCK_TYPE: EXCLUSIVE LOCK_DURATION: EXPLICIT LOCK_STATUS: GRANTED SOURCE: item_func.cc:5482 OWNER_THREAD_ID: 35 OWNER_EVENT_ID: 3 1 row in set (0.00 sec) mysql>
这个结果中的列的含义大多在https://dev.mysql.com/doc/refman/en/metadata-locks-table.html有充分的logging,但有一点值得注意:; OWNER_THREAD_ID
列不包含持有该锁的线程的连接 ID(例如将在PROCESSLIST
或由CONNECTION_ID()
返回CONNECTION_ID()
。 令人困惑的是,术语“线程ID”有时在MySQL文档中被用作“连接ID”的同义词,但这不是其中之一。 如果要确定包含锁的连接的连接标识(例如,要使用KILL
THREAD_ID
连接),则需要查找与performance_schema.threads
表中的THREAD_ID
对应的PROCESSLIST_ID
。 例如,要杀死上面持有我的锁的连接…
mysql> SELECT OWNER_THREAD_ID FROM performance_schema.metadata_locks -> WHERE OBJECT_TYPE='USER LEVEL LOCK' -> AND OBJECT_NAME='foobarbaz'; +-----------------+ | OWNER_THREAD_ID | +-----------------+ | 35 | +-----------------+ 1 row in set (0.00 sec) mysql> SELECT PROCESSLIST_ID FROM performance_schema.threads -> WHERE THREAD_ID=35; +----------------+ | PROCESSLIST_ID | +----------------+ | 10 | +----------------+ 1 row in set (0.00 sec) mysql> KILL 10; Query OK, 0 rows affected (0.00 sec)
另一个简单的方法是使用:
mysqladmin debug
这会将大量信息(包括锁)转储到错误日志中。
从这个职位引用:
你也可以使用这个脚本来查找MySQL中的锁。
SELECT pl.id ,pl.user ,pl.state ,it.trx_id ,it.trx_mysql_thread_id ,it.trx_query AS query ,it.trx_id AS blocking_trx_id ,it.trx_mysql_thread_id AS blocking_thread ,it.trx_query AS blocking_query FROM information_schema.processlist AS pl INNER JOIN information_schema.innodb_trx AS it ON pl.id = it.trx_mysql_thread_id INNER JOIN information_schema.innodb_lock_waits AS ilw ON it.trx_id = ilw.requesting_trx_id AND it.trx_id = ilw.blocking_trx_id
我发现如果你知道锁的名字,可以使用下面的方式
select IS_USED_LOCK('lockname');
但是我没有find任何有关如何列出所有名称的信息。
如果您只想确定是否保留了某个特定的锁,则可以使用IS_USED_LOCK
:
SELECT IS_USED_LOCK('foobar');
如果某个连接持有该锁,则该连接的ID将被返回; 否则,结果是NULL
。