Od MySQL 5.7 jest to możliwe, ale wymaga najpierw włączenia mdl
instrument w performance_schema.setup_instruments
stół. Możesz to zrobić tymczasowo (do następnego restartu serwera), uruchamiając:
UPDATE performance_schema.setup_instruments
SET enabled = 'YES'
WHERE name = 'wait/lock/metadata/sql/mdl';
Lub na stałe, dodając następujące zaklęcie do [mysqld]
sekcja twojego my.cnf
plik (lub jakikolwiek inny plik konfiguracyjny, z którego MySQL odczytuje twoją instalację):
[mysqld]
performance_schema_instrument = 'wait/lock/metadata/sql/mdl=ON'
(Oczywiście, MySQL będzie musiał zostać ponownie uruchomiony, aby zmiana konfiguracji zaczęła obowiązywać, jeśli zastosujesz drugie podejście.)
Blokady zdejmujesz po mdl
instrument został włączony można zobaczyć, uruchamiając SELECT
przeciwko performance_schema.metadata_locks
stół. Jak wspomniano w dokumentacji, GET_LOCK
zamki mają OBJECT_TYPE
z 'USER LEVEL LOCK'
, dzięki czemu możemy przefiltrować nasze zapytanie do nich za pomocą WHERE
klauzula:
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>
Znaczenie kolumn w tym wyniku jest w większości odpowiednio udokumentowane pod adresem https://dev.mysql.com/doc/refman/en/metadata-locks-table.html
, ale warto zwrócić uwagę na jeden problem:OWNER_THREAD_ID
kolumna nie zawierać połączenie ID (jak będzie pokazany w PROCESSLIST
lub zwrócone przez CONNECTION_ID()
) wątku, który posiada blokadę. Myląco, termin „identyfikator wątku” jest czasami używany jako synonim „identyfikatora połączenia” w dokumentacji MySQL, ale to nie jeden z tych czasów. Jeśli chcesz określić połączenie Identyfikator połączenia, które posiada blokadę (na przykład, aby zabić to połączenie za pomocą KILL
), musisz wyszukać PROCESSLIST_ID
który odpowiada THREAD_ID
w performance_schema.threads
stół. Na przykład, aby zabić połączenie, które trzymało moją blokadę powyżej...
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)