显示get_lock中的所有当前锁

bra*_*aer 58 mysql locking

有没有办法选择/显示使用该GET_LOCK功能取出的所有当前锁?

请注意,GET_LOCK锁与表锁不同,就像那些获取的那些LOCK TABLES- 想要知道如何查看这些锁的读者应阅读检测锁定表(由LOCK TABLE锁定)

Mar*_*lff 19

从MySQL 5.7开始,性能模式公开所有元数据锁,包括与该GET_LOCK()函数相关的锁.

请参阅http://dev.mysql.com/doc/refman/5.7/en/metadata-locks-table.html

  • 这为我指明了正确的方向,但是圣牛使我花了很多时间来弄清楚如何使该表实际包含任何东西或一旦我拥有它就可以理解其内容。为了使其他人免于同样的挣扎,我在这里用自己的答案[写了我的发现](http://stackoverflow.com/a/42356351/1709587)。 (2认同)

Mar*_*ery 15

从MySQL 5.7开始,这是可能的,但需要首先启用表中的mdl仪器performance_schema.setup_instruments.您可以通过运行以下命令暂时执行此操作(直到服务器下次重新启动):

UPDATE performance_schema.setup_instruments
SET enabled = 'YES'
WHERE name = 'wait/lock/metadata/sql/mdl';
Run Code Online (Sandbox Code Playgroud)

或永久地,通过将​​以下咒语添加到文件的[mysqld]部分my.cnf(或MySQL在您的安装中读取的任何配置文件):

[mysqld]
performance_schema_instrument = 'wait/lock/metadata/sql/mdl=ON'
Run Code Online (Sandbox Code Playgroud)

(当然,如果采用后一种方法,需要重新启动MySQL才能使配置更改生效.)

锁定你取出mdl仪器已启用可以通过运行可以看出SELECTperformance_schema.metadata_locks表.由于在文档指出,GET_LOCK锁具有OBJECT_TYPE'USER LEVEL LOCK',所以我们可以用下来将它们过滤我们的查询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> 
Run Code Online (Sandbox Code Playgroud)

此结果中列的含义大多在https://dev.mysql.com/doc/refman/en/metadata-locks-table.html中有充分记录,但有一点值得注意的是:该OWNER_THREAD_ID没有包含持有锁的线程的连接 ID(如将显示在其中PROCESSLIST或由返回的CONNECTION_ID()).令人困惑的是,术语"线程ID"有时被用作MySQL文档中"连接ID"的同义词,但这不是其中之一.如果要确定持有锁的连接的连接 ID(例如,为了终止该连接KILL),则需要查找与表PROCESSLIST_ID中对应的连接 ID .例如,要杀死上方锁定我的锁的连接...THREAD_IDperformance_schema.threads

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)
Run Code Online (Sandbox Code Playgroud)

  • +1。写得很好,这里都是正确的。关于 THREAD_ID 与 PROCESSLIST_ID,这确实是一个引起混淆的领域,它与 SHOW PROCESSLIST 有历史渊源。 (2认同)

Rob*_*ert 13

SHOW FULL PROCESSLIST;
Run Code Online (Sandbox Code Playgroud)

你会在那里看到锁

  • OP正在询问应用程序锁定,而这并没有显示那些. (18认同)
  • 请更新您的答案,了解如何使用此命令查看锁定.就我而言,它只会显示当前执行的命令,而不是受锁影响的表. (2认同)
  • **请将此答案否决或作为NAA。** (2认同)

Mar*_*ery 6

如果您只想确定当前是否保留了特定的命名锁,您可以使用IS_USED_LOCK:

SELECT IS_USED_LOCK('foobar');
Run Code Online (Sandbox Code Playgroud)

如果某个连接持有锁,则返回该连接的ID; 否则,结果是NULL.