Da MySQL 5.7 in poi, questo è possibile, ma richiede prima l'abilitazione di mdl
strumento nella performance_schema.setup_instruments
tavolo. Puoi farlo temporaneamente (fino al prossimo riavvio del server) eseguendo:
UPDATE performance_schema.setup_instruments
SET enabled = 'YES'
WHERE name = 'wait/lock/metadata/sql/mdl';
O in modo permanente, aggiungendo il seguente incantesimo a [mysqld]
sezione del tuo my.cnf
file (o qualsiasi altro file di configurazione letto da MySQL durante l'installazione):
[mysqld]
performance_schema_instrument = 'wait/lock/metadata/sql/mdl=ON'
(Naturalmente, MySQL dovrà essere riavviato per rendere effettiva la modifica della configurazione se si adotta quest'ultimo approccio.)
Serrature che elimini dopo il mdl
strumento è stato abilitato può essere visto eseguendo un SELECT
contro performance_schema.metadata_locks
tavolo. Come indicato nei documenti, GET_LOCK
le serrature hanno un OBJECT_TYPE
di 'USER LEVEL LOCK'
, così possiamo filtrare la nostra query fino a loro con un WHERE
clausola:
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>
I significati delle colonne in questo risultato sono per lo più adeguatamente documentati su https://dev.mysql.com/doc/refman/en/metadata-locks-table.html
, ma vale la pena notare un punto di confusione:il OWNER_THREAD_ID
la colonna non contengono la connessione ID (come sarebbe mostrato in PROCESSLIST
o restituito da CONNECTION_ID()
) del filo che tiene il lucchetto. In modo confuso, il termine "thread ID" è talvolta usato come sinonimo di "connection ID" nella documentazione di MySQL, ma questo non una di quelle volte. Se vuoi determinare la connessione ID della connessione che contiene un blocco (ad esempio, per terminare quella connessione con KILL
), dovrai cercare il PROCESSLIST_ID
che corrisponde al THREAD_ID
nella performance_schema.threads
tavolo. Ad esempio, per interrompere la connessione che teneva il mio lucchetto sopra...
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)