Spec-Zone .ru
спецификации, руководства, описания, API
|
Блокировка читала, UPDATE
, или a DELETE
обычно запись набора соединяет каждый индексировала запись, которая
сканируется в обработке SQL-оператора. Не имеет значения, есть ли WHERE
условия в
операторе, который исключил бы строку. InnoDB
не помнит точное WHERE
условие, но только знает, которые индексируют диапазоны, были
отсканированы. Блокировки обычно являются следующими блокировками ключа, которые
также блокируют, сразу вставляет в "разрыв"
перед записью. Однако, блокировка
разрыва может быть отключена явно, который заставляет блокировку следующего ключа не использоваться. Для
получения дополнительной информации см. Раздел
14.2.3.5,"InnoDB
Запись, Разрыв, и Следующие блокировки ключа".
Уровень изоляции транзакции также может влиять, какие блокировки устанавливаются; см. Раздел
13.3.6,"SET TRANSACTION
Синтаксис".
Если вторичное устройство индексирует, используется в поиске, и индексируйте блокировки записи, которые будут
установлены, монопольные, InnoDB
также получает соответствующие записи кластерного
индекса, и наборы соединяет их.
Различия между коллективными и монопольными блокировками описываются в Разделе
14.2.3.2,"InnoDB
Режимы блокировки".
Если Вы имеете, не индексирует подходящий для Вашего оператора, и MySQL должен отсканировать всю таблицу, чтобы обработать оператор, каждая строка таблицы становится заблокированной, который поочередно блокирует всех, вставляет другими пользователями к таблице. Важно создать хороший, индексирует так, чтобы Ваши запросы излишне не отсканировали много строк.
Для SELECT ...
FOR UPDATE
или SELECT ... LOCK IN SHARE MODE
, блокировки получаются за отсканированные строки,
и, как ожидают, будут выпущены для строк, которые не имеют право на включение в набор результатов (например,
если они не соответствуют критериям, поданным WHERE
пункт). Однако, в некоторых
случаях, строки не могли бы быть сразу разблокированы, потому что отношение между строкой результата и ее
первоисточником теряется во время выполнения запроса. Например, в a UNION
, отсканированный (и заблокированный) строки от таблицы могли бы быть
вставлены во временную таблицу перед оценкой, имеют ли они право на набор результатов. При этом обстоятельстве
теряется отношение строк во временной таблице к строкам в исходной таблице, и последние строки не разблокированы
до конца выполнения запроса.
InnoDB
определенные типы наборов блокировок следующим образом.
SELECT ... FROM
непротиворечивое чтение, читая снимок базы данных и не
устанавливая блокировок, если уровень изоляции транзакции не устанавливается в SERIALIZABLE
. Для SERIALIZABLE
уровень, поиск устанавливает совместно использованные
следующие блокировки ключа на индексировать записях, с которыми это встречается.
SELECT ... FROM ... LOCK IN SHARE MODE
наборы совместно использованные
следующие блокировки ключа на всех индексируют записи поиск, встречаются.
Для индексируют записи, с которыми поиск встречается, SELECT ... FROM ... FOR UPDATE
блокирует другие сеансы от выполнения SELECT
... FROM ... LOCK IN SHARE MODE
или от чтения в определенных уровнях изоляции транзакции.
Непротиворечивые чтения проигнорируют любой набор блокировок на записях, которые существуют в
представлении чтения.
UPDATE ... WHERE ...
устанавливает монопольную следующую блокировку ключа
на каждой записи, с которой встречается поиск.
DELETE FROM ... WHERE ...
устанавливает монопольную следующую блокировку
ключа на каждой записи, с которой встречается поиск.
INSERT
устанавливает монопольную блокировку на вставленной строке. Эта
блокировка является блокировкой индексировать-записи, не следующей блокировкой ключа (то есть, нет
никакой блокировки разрыва), и не препятствует тому, чтобы другие сеансы вставили в разрыв перед
вставленной строкой.
До вставки строки устанавливается тип блокировки разрыва, названной блокировкой разрыва намерения вставки. Эта блокировка сигнализирует намерение вставить таким способом, которым многократные транзакции, вставляющие в то же самое, индексируют разрыв, не должен ожидать друг друга, если они не вставляют в той же самой позиции в пределах разрыва. Предположите, что есть, индексируют записи со значениями 4 и 7. Отдельные транзакции, которые пытаются вставить значения 5 и 6 каждых блокировок разрыв между 4 и 7 с блокировками намерения вставки до получения монопольной блокировки на вставленной строке, но не блокировать друг друга, потому что строки неконфликтуют.
Если двойная ключевая ошибка происходит, коллективная блокировка на копии индексируют запись,
устанавливается. Это использование коллективной блокировки может привести к мертвой блокировке,
должны там быть многократные сеансы, пытающиеся вставить ту же самую строку, если у другого сеанса
уже есть монопольная блокировка. Это может произойти, если другой сеанс удаляет строку. Предположите
что InnoDB
таблица t1
имеет следующую
структуру:
CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;
Теперь предположите, что три сеанса выполняют следующие операции в порядке:
Сеанс 1:
START TRANSACTION;INSERT INTO t1 VALUES(1);
Сеанс 2:
START TRANSACTION;INSERT INTO t1 VALUES(1);
Сеанс 3:
START TRANSACTION;INSERT INTO t1 VALUES(1);
Сеанс 1:
ROLLBACK;
Первая работа сеансом 1 получает монопольную блокировку для строки. Операции сеансами 2 и 3 и результат по двойной ключевой ошибке и они оба запрашивают коллективную блокировку на строку. Когда сеанс 1 откатывает, он выпускает свою монопольную блокировку на строке, и запросы коллективной блокировки с очередями на сеансы 2 и 3 предоставляют. В этой точке, сеансы 2 и 3 мертвых блокировки: Ни один не может получить монопольную блокировку для строки из-за коллективной блокировки, сохраненной другим.
Подобная ситуация происходит, если таблица уже содержит строку со значением ключа, 1 и три сеанса выполняют следующие операции в порядке:
Сеанс 1:
START TRANSACTION;DELETE FROM t1 WHERE i = 1;
Сеанс 2:
START TRANSACTION;INSERT INTO t1 VALUES(1);
Сеанс 3:
START TRANSACTION;INSERT INTO t1 VALUES(1);
Сеанс 1:
COMMIT;
Первая работа сеансом 1 получает монопольную блокировку для строки. Операции сеансами 2 и 3 и результат по двойной ключевой ошибке и они оба запрашивают коллективную блокировку на строку. Когда сеанс 1 фиксация, это выпускает свою монопольную блокировку на строке, и запросы коллективной блокировки с очередями на сеансы 2 и 3 предоставляют. В этой точке, сеансы 2 и 3 мертвых блокировки: Ни один не может получить монопольную блокировку для строки из-за коллективной блокировки, сохраненной другим.
INSERT ... ON DUPLICATE KEY UPDATE
отличается от простого INSERT
в этом монопольная следующая блокировка ключа, а не коллективная
блокировка помещается в строку, которая будет обновлена, когда двойная ключевая ошибка происходит.
REPLACE
делается как INSERT
если нет никакой коллизии на уникальном ключе. Иначе, монопольная
следующая блокировка ключа помещается в строку, которая будет заменена.
INSERT INTO T SELECT ... FROM S WHERE ...
наборы
монопольное индексирует запись без разрыва, соединяют каждую строку, вставленную в T
. Если уровень изоляции транзакции READ COMMITTED
или innodb_locks_unsafe_for_binlog
включается, и уровень изоляции
транзакции не SERIALIZABLE
,
InnoDB
делает поиск на S
как непротиворечивое
чтение (никакие блокировки). Иначе, InnoDB
наборы совместно использованные
следующие блокировки ключа на строках от S
. InnoDB
должен установить привязывает последний случай: В восстановлении
отката вперёд после резервного копирования каждый SQL-оператор должен быть выполнен точно таким же
образом, это было сделано первоначально.
CREATE TABLE ... SELECT ...
выполняет SELECT
с совместно используемыми следующими блокировками ключа или
как непротиворечивое чтение, что касается INSERT ... SELECT
.
Когда a SELECT
используется в конструкциях REPLACE
INTO t SELECT ... FROM s WHERE ...
или UPDATE t ... WHERE col IN
(SELECT ... FROM s ...)
, InnoDB
наборы совместно использованные
следующие блокировки ключа на строках от таблицы s
.
Инициализируя ранее указанный AUTO_INCREMENT
столбец
на таблице, InnoDB
устанавливает монопольную блокировку на конце
индексирования связанного с AUTO_INCREMENT
столбец. В доступе к
автоинкрементному счетчику, InnoDB
использует определенное AUTO-INC
режим блокировки таблицы, где блокировка длится только до конца
текущего SQL-оператора, не до конца всей транзакции. Другие сеансы не могут вставить в таблицу в то
время как AUTO-INC
блокировка таблицы сохранена; см. Раздел
14.2.3.1," InnoDB
Модель транзакции и Блокировка".
InnoDB
выбирает значение ранее инициализированный AUTO_INCREMENT
столбец, не устанавливая блокировок.
Если a FOREIGN KEY
ограничение определяется на
таблице, любой вставляет, обновляет, или удаляет, который требует, чтобы ограничительное условие было
проверено наборы совместно использованные блокировки на уровне записи на записях, что это смотрит на
проверить ограничение. InnoDB
также наборы, они привязывают случай, где
ограничение перестало работать.
LOCK
TABLES
блокировки таблицы наборов, но это - более высокий уровень MySQL выше InnoDB
уровень, который устанавливает эти блокировки. InnoDB
знает о блокировках таблицы если innodb_table_locks = 1
(значение по
умолчанию) и autocommit
= 0
, и уровень MySQL выше InnoDB
знает о блокировках на
уровне строки.
Иначе, InnoDB
's автоматическое обнаружение мертвой блокировки не может
обнаружить мертвые блокировки, где такие блокировки таблицы включаются. Кроме того, потому что в
этом случае более высокий уровень MySQL не знает о блокировках на уровне строки, возможно получить
блокировку таблицы на таблице, где у другого сеанса в настоящий момент есть блокировки на уровне
строки. Однако, это не подвергает опасности целостность транзакции, как обсуждено в Разделе
14.2.3.9, "Обнаружение мертвой блокировки и Откат". См. также Раздел
14.2.7, "Пределы на InnoDB
Таблицы".