Show all current locks from get_lock

半城伤御伤魂 提交于 2019-11-30 01:08:49

Starting with MySQL 5.7, the performance schema exposes all metadata locks, including locks related to the GET_LOCK() function.

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

SHOW FULL PROCESSLIST;

You will see the locks in there

From MySQL 5.7 onwards, this is possible, but requires first enabling the mdl instrument in the performance_schema.setup_instruments table. You can do this temporarily (until the server is next restarted) by running:

UPDATE performance_schema.setup_instruments
SET enabled = 'YES'
WHERE name = 'wait/lock/metadata/sql/mdl';

Or permanently, by adding the following incantation to the [mysqld] section of your my.cnf file (or whatever config files MySQL reads from on your installation):

[mysqld]
performance_schema_instrument = 'wait/lock/metadata/sql/mdl=ON'

(Naturally, MySQL will need to be restarted to make the config change take effect if you take the latter approach.)

Locks you take out after the mdl instrument has been enabled can be seen by running a SELECT against the performance_schema.metadata_locks table. As noted in the docs, GET_LOCK locks have an OBJECT_TYPE of 'USER LEVEL LOCK', so we can filter our query down to them with a WHERE clause:

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> 

The meanings of the columns in this result are mostly adequately documented at https://dev.mysql.com/doc/refman/en/metadata-locks-table.html, but one point of confusion is worth noting: the OWNER_THREAD_ID column does not contain the connection ID (like would be shown in the PROCESSLIST or returned by CONNECTION_ID()) of the thread that holds the lock. Confusingly, the term "thread ID" is sometimes used as a synonym of "connection ID" in the MySQL documentation, but this is not one of those times. If you want to determine the connection ID of the connection that holds a lock (for instance, in order to kill that connection with KILL), you'll need to look up the PROCESSLIST_ID that corresponds to the THREAD_ID in the performance_schema.threads table. For instance, to kill the connection that was holding my lock above...

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)

If you just want to determine whether a particular named lock is currently held, you can use IS_USED_LOCK:

SELECT IS_USED_LOCK('foobar');

If some connection holds the lock, that connection's ID will be returned; otherwise, the result is NULL.

I found following way which can be used if you KNOW name of lock

select IS_USED_LOCK('lockname');

however i not found any info about how to list all names.

Sonicthoughts

Another easy way is to use:

mysqladmin debug 

This dumps a lot of information (including locks) to the error log.

Reference taken from this post:

You can also use this script to find lock in 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
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!