it-swarm.xyz

Как я могу показать блокировки MySQL?

Есть ли способ показать все блокировки, которые активны в базе данных mysql?

54
Rory

См. Ссылку Марко для таблиц InnoDB и предостережений.

Для MyISAM не существует простого решения "это оскорбительный запрос". Вы должны всегда начинать с списка процессов. Но обязательно включите полное ключевое слово, чтобы печатные запросы не усекались:

SHOW FULL PROCESSLIST;

Это покажет вам список всех текущих процессов, их SQL-запросов и состояния. Теперь обычно, если один запрос вызывает блокировку многих других, его будет легко идентифицировать. У затронутых запросов будет состояние Locked, а вызывающий беспокойство запрос будет сам по себе, возможно, ожидая чего-то интенсивного, например временной таблицы.

Если это неочевидно, вам придется использовать свои способности к выводу SQL, чтобы определить, какой кусок нарушающего SQL может быть причиной ваших проблем.

47
Dan Carley

Если вы используете InnoDB и вам нужно проверить запущенные запросы, я рекомендую

show engine innodb status;

как упомянуто в ссылке Марко. Это даст вам запрос блокировки, сколько строк/таблиц заблокировано им и т.д. Смотрите в разделе СДЕЛКИ.

Проблема с использованием SHOW PROCESSLIST означает, что вы не увидите блокировки, если другие запросы не будут поставлены в очередь.

26
Polymorphix

Пытаться SHOW OPEN TABLES :

show open tables where In_Use > 0 ;
24
M Sleman

Ни один из ответов не может показать все блокировки, которые в данный момент удерживаются.

Сделайте это, например в MySQL в терминале.

start transaction;
update someTable set name="foobar" where ID=1234;
-- but no rollback or commit - just let it sit there

Понятно, что транзакция выше удерживает блокировку, потому что транзакция все еще активна. Но сейчас не выполняется никаких запросов, и никто нигде не ждет блокировки (пока, по крайней мере).

INFORMATION_SCHEMA.INNODB_LOCKS пусто, что имеет смысл, учитывая документация , потому что есть только одна транзакция, и в настоящее время никто не ожидает каких-либо блокировок. Также INNODB_LOCKS все равно не рекомендуется.

SHOW ENGINE INNODB STATUS бесполезен: someTable вообще не упоминается

SHOW FULL PROCESSLIST пусто, потому что преступник сейчас не выполняет запрос.

Ты можешь использовать INFORMATION_SCHEMA.INNODB_TRX, performance_schema.events_statements_history а также performance_schema.threads для извлечения запросов, которые любые активные транзакции выполняли в прошлом, как описано в мой другой ответ , но я не нашел способа увидеть, что someTable заблокировано в вышеуказанный сценарий.

Предложения в других ответах пока не помогут, по крайней мере.

Отказ от ответственности: у меня не установлен innotop, и я не стал беспокоиться. Возможно, что может работать.

11
Peter V. Mørch

Используя эту команду

SHOW PROCESSLIST

покажет все процессы, запущенные в данный момент, включая процесс, получивший блокировку для таблиц.

7
Arie K

AFAIK, в MYSQL до сих пор нет собственного пути, но я использую innotop . Это бесплатно и имеет много других функций.

Также смотрите эта ссылка для получения дополнительной информации об использовании инструмента innotop.

7
Marko Carter

Ссылка взята из этого поста.

Вы можете использовать ниже скрипт:

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
5
Anvesh