Desde MySQL 5.7 en adelante, esto es posible, pero primero requiere habilitar el mdl
instrumento en el performance_schema.setup_instruments
mesa. Puede hacer esto temporalmente (hasta que el servidor se reinicie la próxima vez) ejecutando:
UPDATE performance_schema.setup_instruments
SET enabled = 'YES'
WHERE name = 'wait/lock/metadata/sql/mdl';
O permanentemente, agregando el siguiente conjuro al [mysqld]
sección de su my.cnf
(o cualquier archivo de configuración que lea MySQL en su instalación):
[mysqld]
performance_schema_instrument = 'wait/lock/metadata/sql/mdl=ON'
(Naturalmente, será necesario reiniciar MySQL para que el cambio de configuración surta efecto si adopta el último enfoque).
Candados que quitas después el mdl
el instrumento ha sido habilitado se puede ver ejecutando un SELECT
contra el performance_schema.metadata_locks
mesa. Como se indica en los documentos, GET_LOCK
los candados tienen un OBJECT_TYPE
de 'USER LEVEL LOCK'
, para que podamos filtrar nuestra consulta hacia ellos con un 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>
Los significados de las columnas en este resultado están documentados adecuadamente en su mayoría en https://dev.mysql.com/doc/refman/en/metadata-locks-table.html
, pero vale la pena señalar un punto de confusión:el OWNER_THREAD_ID
la columna no contener la conexión ID (como se mostraría en PROCESSLIST
o devuelto por CONNECTION_ID()
) del hilo que sujeta el mechón. De manera confusa, el término "ID de subproceso" a veces se usa como sinónimo de "ID de conexión" en la documentación de MySQL, pero esto no una de esas veces Si desea determinar la conexión ID de la conexión que tiene un bloqueo (por ejemplo, para eliminar esa conexión con KILL
), deberá buscar el PROCESSLIST_ID
que corresponde al THREAD_ID
en el performance_schema.threads
mesa. Por ejemplo, para eliminar la conexión que retenía mi candado arriba...
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)