Мертвые блокировки на строках удаления MySQL

Если Вы уже нормализуете исходные данные к булевским переменным, то! = xor.

bool(a) != bool(b)
10
задан ChrisInEdmonton 20 August 2009 в 15:18
поделиться

2 ответа

При выполнении операций DML , InnoDB блокирует все отсканированные строки, не сопоставленные.

Рассмотрим этот макет таблицы:

DROP TABLE t_tran;

CREATE TABLE t_tran (id INT NOT NULL PRIMARY KEY, data INT NOT NULL, KEY ix_tran_data (data)) Engine=InnoDB;

DROP TABLE t_tran;

CREATE TABLE t_tran (id INT NOT NULL PRIMARY KEY, data INT NOT NULL, KEY ix_tran_data (data)) Engine=InnoDB;

INSERT
INTO    t_tran
VALUES
(1, 1),
(2, 2),
(3, 3),
(4, 4),
(5, 5),
(6, 6),
(7, 7),
(8, 8);

START TRANSACTION;

DELETE
FROM    t_tran
WHERE   data = 2
        AND id <= 5;

В данном случае MySQL ] выбирает путь доступа RANGE для id , что он считает более дешевым, чем REF для данных .

В параллельной транзакции вы сможет удалять или обновлять строки 6 , 7 , 8 , но не строки 1 до 5 , поскольку они заблокированы (несмотря на то, что была затронута только строка 2 ).

Если вы удалите id <= 5 из условия выше, вы сможете удалить любую строку но строка 3 .

К сожалению,вы не можете контролировать пути доступа MySQL в операциях DML .

Лучшее, что вы можете сделать, - это правильно проиндексировать ваши условия и надеяться, что MySQL выберет эти индексы.

5
ответ дан 4 December 2019 в 02:50
поделиться

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

Вы можете проверить, выполнив следующее:

SHOW VARIABLES LIKE 'tx%';

Чтобы установить это, в вашем файле my.cnf введите следующую строку:

tx_isolation=READ-COMMITTED
2
ответ дан 4 December 2019 в 02:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: