A partir do MySQL 5.7, isso é possível, mas requer primeiro habilitar o
mdl
instrumento no performance_schema.setup_instruments
tabela. Você pode fazer isso temporariamente (até que o servidor seja reiniciado) executando:UPDATE performance_schema.setup_instruments
SET enabled = 'YES'
WHERE name = 'wait/lock/metadata/sql/mdl';
Ou permanentemente, adicionando o seguinte encantamento ao
[mysqld]
seção do seu my.cnf
arquivo (ou qualquer arquivo de configuração que o MySQL leia em sua instalação):[mysqld]
performance_schema_instrument = 'wait/lock/metadata/sql/mdl=ON'
(Naturalmente, o MySQL precisará ser reiniciado para que a alteração de configuração tenha efeito se você adotar a última abordagem.)
Bloqueios que você tira depois o
mdl
instrumento foi habilitado pode ser visto executando um SELECT
contra o performance_schema.metadata_locks
tabela. Conforme observado nos documentos, GET_LOCK
os cadeados têm um OBJECT_TYPE
de 'USER LEVEL LOCK'
, para que possamos filtrar nossa consulta para eles com um WHERE
cláusula: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>
Os significados das colunas neste resultado estão documentados adequadamente em https://dev.mysql.com/doc/refman/en/metadata-locks-table.html , mas vale a pena notar um ponto de confusão:o
OWNER_THREAD_ID
coluna não conter a conexão ID (como seria mostrado na PROCESSLIST
ou retornado por CONNECTION_ID()
) do thread que mantém o bloqueio. Confusamente, o termo "ID de thread" às vezes é usado como sinônimo de "ID de conexão" na documentação do MySQL, mas isso não uma dessas vezes. Se você deseja determinar a conexão ID da conexão que mantém um bloqueio (por exemplo, para encerrar essa conexão com KILL
), você precisará procurar o PROCESSLIST_ID
que corresponde ao THREAD_ID
no performance_schema.threads
tabela. Por exemplo, para matar a conexão que estava segurando meu bloqueio acima ... 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)