Подтвердить что ты не робот

Показать все текущие блокировки из get_lock

Есть ли способ выбрать/показать все текущие блокировки, которые были сняты с помощью GET_LOCK function?

Обратите внимание, что блокировки GET_LOCK отличаются от блокировок таблиц, таких как те, которые получены с помощью LOCK TABLES - читателей, которые хотят знать, как видеть эти блокировки, должны читать Обнаружение заблокированных таблиц (заблокировано по LOCK TABLE)

4b9b3361

Ответ 1

Начиная с MySQL 5.7, схема производительности предоставляет все блокировки метаданных, включая блокировки, связанные с функцией GET_LOCK().

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

Ответ 2

SHOW FULL PROCESSLIST;

Вы увидите блокировки там

Ответ 3

Начиная с MySQL 5.7, это возможно, но сначала требуется включить инструмент mdl в таблице performance_schema.setup_instruments. Вы можете сделать это временно (до следующего перезапуска сервера), выполнив:

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

Или навсегда, добавив следующее заклинание в раздел [mysqld] вашего файла my.cnf (или любые файлы конфигурации, которые MySQL читает из вашей установки):

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

(Естественно, MySQL нужно будет перезапустить, чтобы изменения конфигурации вступили в силу, если вы примете последний подход.)

Блокировки, которые вы вынимаете после включения инструмента mdl, можно увидеть, запустив SELECT в таблице performance_schema.metadata_locks, Как отмечено в документах, блокировки GET_LOCK имеют OBJECT_TYPE 'USER LEVEL LOCK', поэтому мы можем отфильтровать наш запрос до них с помощью предложения WHERE:

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> 

Значения столбцов в этом результате в значительной степени документируются в https://dev.mysql.com/doc/refman/en/metadata-locks-table.html, но стоит упомянуть одну точку смятения: t214 > не содержит идентификатор соединения (например, будет показан в PROCESSLIST или возвращен CONNECTION_ID()) потока, который содержит блокировку. Смутно, термин "идентификатор потока" иногда используется как синоним "идентификатора соединения" в документации MySQL, но это не одно из тех случаев. Если вы хотите определить идентификатор соединения, в котором хранится блокировка (например, чтобы убить это соединение с помощью KILL) вам нужно найти PROCESSLIST_ID, который соответствует THREAD_ID в таблице performance_schema.threads. Например, чтобы убить соединение, которое удерживало мой замок выше...

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)

Ответ 4

Если вы просто хотите определить, находится ли конкретная именованная блокировка в настоящее время, вы можете использовать IS_USED_LOCK:

SELECT IS_USED_LOCK('foobar');

Если какое-либо соединение содержит блокировку, этот идентификатор соединения будет возвращен; в противном случае результат NULL.

Ответ 5

Другим простым способом является использование:

mysqladmin debug 

Это сбрасывает много информации (включая блокировки) в журнал ошибок.

Ответ 6

Я нашел следующий способ, который можно использовать, если вы ЗНАЕТ имя блокировки

select IS_USED_LOCK('lockname');

однако я не нашел никакой информации о том, как перечислить все имена.

Ответ 7

Ссылка, взятая из этой публикации:

Вы также можете использовать этот script для поиска блокировки в 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