Я использую MySQL таблицы InnoDB и пытаюсь понять причины некоторой блокировки на уровне строк в случае сканирования диапазона индекса. Я обнаружил, что дополнительная запись индекса (вне диапазона) может быть заблокирована в зависимости от уникальности используемого индекса. См. Пример ниже (проверено в версии 8.0.18).
CREATE TABLE foo (
a INT NOT NULL,
b INT NOT NULL,
c CHAR(1) NOT NULL,
PRIMARY KEY (a),
UNIQUE KEY (b)
) ENGINE=InnoDB;
INSERT INTO foo VALUES (1,1,'A'), (3,3,'B'), (5,5,'C'), (7,7,'D'), (9,9,'E');
Контрольный пример 1
Сессия 1:
START TRANSACTION;
SELECT * FROM foo WHERE a < 2 FOR UPDATE;
Сессия 2:
DELETE FROM foo WHERE a = 3; -- Success
Контрольный пример 2
При этом используются исходные строки таблицы с возвращенной удаленной записью.
Сессия 1:
START TRANSACTION;
SELECT * FROM foo WHERE b < 2 FOR UPDATE;
Сессия 2:
DELETE FROM foo WHERE b = 3; -- Blocks
Блокировка записи вторичного индекса с b = 3 во втором тестовом случае выглядит ненужной.
Почему InnoDB блокирует следующий индекс запись справа от сканируемого диапазона в случае вторичного индекса? Есть ли практическая причина для этого? Может кто-нибудь привести пример проблемы, которая может возникнуть, если запись с b = 3 не заблокирована во втором тестовом примере?