Хорошо, я думаю, что-то понял.Может быть, это будет полезно для кого-то, так как я не нашел объяснения в другом месте.Причина, по которой innodb_table_locks = 0 не работает для LOCK TABLE WRITE , заключается в том, что блокировки таблиц также передаются MDL (диспетчером блокировки метаданных).Однако поведение для LOCK TABLE READ отличается в версиях> = 5.7, и я думаю, что документы устарели.
Вот пример:
#connection 1
drop table if exists t1;
create table t1 (id integer primary key, x integer) engine=INNODB;
insert into t1 values(0, 0),(1,1),(2,2);
begin;
SELECT * FROM t1 WHERE x = 0 FOR UPDATE;
Этот зависнет, так как он пытается получить блокировку innodb S на столе, в то время как первое соединение удерживает innodb IX блокировка.
#connection 2
set @@autocommit=0;
lock table t1 READ;
Эта попытка будет успешной в 5.6, так как блокировка innodb отключена и MDL MDL_SHARED_READ совместим с MDL_SHARED_WRITE .Однако в 5.7 и выше он также будет зависать, потому что они ввели новый тип блокировки MDL_SHARED_READ_ONLY , который не совместим с MDL_SHARED_WRITE .
#connection 3
set @@autocommit=0;
set @@innodb_table_locks = 0;
lock table t1 READ;
Комментарий оттекущие тестовые случаи MYSQL:
Старый метод блокировки (где LOCK TABLE был проигнорирован InnoDB) больше не работает, когда используется LOCK TABLE ... WRITE из-за исправления ошибок # 46272 "MySQL 5.4.4, новый MDL: ненужный и ошибка # 37346 «innodb не обнаруживает тупик между обновлением и изменением таблицы». После того, как WL № 6671 «Улучшить масштабируемость за счет отсутствия использования блокировок thr_lock.c для таблиц InnoDB», он больше не работает для LOCK TABLES READтакже. LOCK TABLES блокировки теперь полностью обрабатываются подсистемой MDL.
Итак, я думаю, что им нужно обновить документы в 5.7 и более поздних версиях, чтобы упомянуть, что они больше не работают даже для LOCK TABLE READ ;