Страницы

Поиск по вопросам

среда, 12 декабря 2018 г.

Почему один запрос к MySQL отражается на выполнении следующего

UPDATE `table` SET `link`=0 where `link`=X AND `type` IN (LIST); DELETE FROM `table` where `link`=X; В целевой таблице table удаляются (update) ссылки у строк определенного типа. Затем происходит удаление оставшихся. При этом второй запрос происходит очень долго, драйвер падает с ошибкой таймаута. Если первый запрос не выполнять, то второй, на удаление, пройдет быстро. Индекс на поле link имеется. Во время работы второго запроса processlist показывает state = updating | Query | 27 | updating | DELETE FROM `table` WHERE `table`.`link` = ? Как с этим бороться? v5.6.16 p.s. Обе операции происходят внутри транзакции, если операцию на обновление вынести до старта транзакции, то проблем не наблюдается.


Ответ

Если запускать транзакцию и пытаться обновить часть строк по некоторому ключу, затем удалить (думаю это же относится и к обновлению) другие строки используя этот же ключ (индекс), то строки затронутые первым запросом будут заблокированы и следующий будет ждать снятия блокировки. Посмотреть в этот момент на сам зависший запрос можно так show full processlist; Посмотреть на текущие блокировки можно так select * from information_schema.innodb_locks; Информацию о транзакциях так SHOW ENGINE INNODB STATUS Снижение уровня изоляции транзакции при этом не решает задачу. Пока я вижу единственный работающий выход: выяснить какие из строк нужно обновить, какие удалить и выполнить два запроса используя при этом их первичные ключи, а не общие как было раньше.

Комментариев нет:

Отправить комментарий