MySQL 5.6 - тупик для блокировки одних и тех же строк дважды?

Я вижу тупик с MySQL 5.6 из-за того, что кажется, будто пытаюсь дважды заблокировать одну и ту же строку.

Из приведенного ниже фрагмента строки с id = (11, 12, 13, 14, 15) уже имеют блокировку. И когда другая транзакция попыталась заблокировать их, MySQL не смог выполнить транзакцию, обнаружив тупик.

Я правильно понимаю это? Если да, то есть ли что-нибудь в MySQL 5.6, чтобы справиться с этим? FWIW, тот же код в 5.5 работал нормально (несколько сотен итераций).

------------------------
LATEST DETECTED DEADLOCK
------------------------
2013-07-25 11:46:05 13a515000
*** (1) TRANSACTION:
TRANSACTION 2333130, ACTIVE 0 sec fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 31 lock struct(s), heap size 6960, 6 row lock(s)
MySQL thread id 2944, OS thread handle 0x13ae88000, query id 184533 localhost 127.0.0.1 root Sending data
SELECT id FROM table_meta WHERE id IN (11, 12, 13, 14, 15) FOR UPDATE
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 128954 page no 5 n bits 176 index `PRIMARY` of table `db_test1`.`table_meta` trx id 2333130 lock_mode X locks rec but not gap waiting
*** (2) TRANSACTION:
TRANSACTION 2333255, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1248, 11 row lock(s)
MySQL thread id 2927, OS thread handle 0x13a515000, query id 186769 localhost 127.0.0.1 root Sending data
SELECT id FROM table_meta WHERE id IN (1, 2, 3, 4, 5, 6, 8, 10, 11, 12, 13, 14, 15) FOR UPDATE
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 128954 page no 5 n bits 176 index `PRIMARY` of table `db_test1`.`table_meta` trx id 2333255 lock_mode X locks rec but not gap
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 128954 page no 5 n bits 176 index `PRIMARY` of table `db_test1`.`table_meta` trx id 2333255 lock_mode X locks rec but not gap waiting
*** WE ROLL BACK TRANSACTION (2)

person Shri Javadekar    schedule 26.07.2013    source источник
comment
Даже я видел то же самое .... с нетерпением жду обновления ....   -  person Uday    schedule 25.09.2013


Ответы (2)


Конечно,

Просто отсортировал это для одного из моих клиентов в 5.6. На самом деле это взаимоблокировки innodb, за выбором следует обновление, которое вызывает взаимоблокировки. Пожалуйста, обновите запрос и сделайте отдельное обновление.

У вас есть подчиненный сервер?

Еще одна вещь, которую следует учитывать - INSERT… SELECT также выполняет чтение в режиме блокировки и, таким образом, частично обходит управление версиями и извлекает последнюю зафиксированную строку. Таким образом, даже если вы выполняете операцию в режиме REPEATABLE-READ, эта операция будет выполняться в режиме READ-COMMITTED, потенциально давая другой результат по сравнению с тем, что дал бы чистый SELECT. Это, кстати, относится также к SELECT .. LOCK IN SHARE MODE и SELECT… FOR UPDATE. Один из моих вопросов - что делать, если я не использую репликацию и мой двоичный журнал отключен? Если репликация не используется, вы можете включить опцию innodb_locks_unsafe_for_binlog, которая ослабит блокировки, которые Innodb устанавливает при выполнении инструкции, что обычно обеспечивает лучший параллелизм. Однако, как следует из названия, это делает блокировки небезопасными для репликации и восстановления на определенный момент времени, поэтому используйте параметр innodb_locks_unsafe_for_binlog с осторожностью.

person Masood Alam    schedule 01.10.2013

Легкий способ;

  1. Попытайтесь выяснить таблицы, участвующие в тупиковых случаях;
  2. Определите, какая таблица должна иметь предпочтение перед другими с точки зрения INSERT / UPDATE / DELETE;
  3. Просто оберните соответствующий запрос операторами LOCK TABLES ... UNLOCK TABLES (вы должны использовать псевдоним, если он есть)

Будем надеяться, что не все операторы / таблицы потребуют такого заключения, а только самое важное.

person Broken Arrow    schedule 12.07.2021