Количество слов: 3107 слов. Время чтения около 10 минут.
Промежуток в MySQL относится к пространству между двумя индексными ключами в индексе. Блокировка разрыва используется для предотвращения фантомного чтения во время запросов диапазона и обеспечения согласованности и безопасности параллелизма результатов запроса.
Блокировка записи
Блокировку записей также называют блокировкой строк. Как следует из названия, она блокирует записи строк в базе данных.
например:
SELECT * FROM `user` WHERE `id`=1 FOR UPDATE;
Вышеупомянутый SQL будет в id=1
Добавьте блокировку записи к записи строки, чтобы другие транзакции не могли вставлять, обновлять или удалять эту строку.
Гэп Лок
Блокировка пробелов предназначена для блокировки пробелов и используется для блокировки пробелов между диапазонами индексов, чтобы другие транзакции не могли вставлять новые данные в этот диапазон. Блокировки пробелов — это эксклюзивные блокировки, которые не позволяют другим транзакциям вставлять значения, соответствующие условиям в пробелах. Блокировки пробелов эффективны только при уровне изоляции повторяемого чтения.
Подробности блокировки зазора будут обсуждаться ниже. Это лишь концептуальное введение.
Блокировка следующего ключа
Временная блокировка ключа состоит из блокировки записи и блокировки промежутков. Она добавляет блокировку записей к записям в диапазоне индекса и добавляет блокировку промежутков между диапазонами индексов. Это позволит избежать проблемы фантомного чтения и обеспечить изоляцию транзакций.
Помните: интервал замка зазора оставлен открытым, а правый открыт, интервал замка ключа оставлен открытым, а правый закрыт.
Замки с зазором являются основой обеспечения нормальной работы замков с ключом. Понимание концепции замков с зазором очень важно для глубокого понимания этих трех типов замков.
Диапазон блокировки блокировки зазора относится к зазору между диапазонами индексов.
Для иллюстрации приведем простой пример:
Предположим, существует файл с именемproducts
стол,Есть целочисленный столбецproduct_id
как первичный ключиндекс。Их сейчас двоеодновременнодела:Транзакция Аи Транзакция Б。
Транзакция А выполняет следующий оператор:
BEGIN;
SELECT * FROM `products` WHERE `product_id` BETWEEN 100 and 200 FOR UPDATE;
Транзакция B выполняет следующий оператор:
BEGIN;
INSERT INTO `products` (`product_id`, `name`) VALUES (150, 'Product 150');
В этом случае Транзакция Абудет внутриproducts
в таблицеproduct_id
Значение 100 и 200 Установите блокировку пробела в диапазоне между ними. Поэтому в Транзакции Во время работы А другие дела не могут вставлять новые данные в этот диапазон, в Транзакции. Бпопробуй вставитьproduct_id
для150записи,Поскольку запись находится в Транзакция А заблокирован в диапазоне разрыва, Транзакция Ббудетблокировать,до Транзакция А до тех пор, пока не будет снят фиксатор зазора.
На уровне изоляции транзакции «Повторяемое чтение» (Repeatable Read) блокировки пробелов будут возникать в следующих ситуациях:
Следует отметить, что описанная выше ситуация будет генерировать блокировки только на уровне изоляции повторяемого чтения. На других уровнях изоляции, таких как уровень изоляции Read Committed, MySQL может использовать временные блокировки намерений, чтобы избежать проблем параллелизма, вместо создания настоящих блокировок пробелов.
Почему акцент здесь сделан на обычных индексах? Поскольку блокировка уникального индекса не вызывает блокировку пробелов, рассмотрим следующий пример:
гипотезау нас есть имядляstudents
стол,там два поля:id и имя. id является первичным ключом, и теперь одновременно выполняются две транзакции:
Транзакция А выполняет следующий оператор:
SELECT * FROM students WHERE id = 1 FOR UPDATE;
Транзакция B выполняет следующий оператор:
INSERT INTO students (id, name) VALUES (2, 'John');
Поскольку транзакция A использует блокировку уникального индекса, она заблокирует запись с идентификатором 1 и не вызовет блокировку пробела. В то же время вставка записи с идентификатором 2 в транзакцию B не повлияет. Это связано с тем, что уникальный индекс будет блокировать только определенные записи, соответствующие критериям, а не записи, которые не существуют (например, пробелы).
При блокировке существующей записи с помощью уникального индекса вместо пробельных блокировок используются блокировки записей.
Однако если условие поиска включает только часть столбцов многостолбцового уникального индекса, могут возникнуть блокировки с пробелами. Вот пример:
гипотезаstudents
поверхность,Содержит три столбца:id、nameиage。мы(name, Создается уникальный индекс по возрасту).
Теперь одновременно работают две транзакции:
Транзакция А выполняет следующий оператор:
SELECT * FROM students WHERE name = 'John' FOR UPDATE;
Транзакция B выполняет следующий оператор:
INSERT INTO students (id, name, age) VALUES (2, 'John', 25);
В этом случае условие поиска транзакции A включает только часть уникального столбца индекса (имя), но не включает полный столбец индекса (имя, возраст). Таким образом, MySQL добавит блокировки строк к совпадающим записям, а также добавит блокировки пробелов к пробелам, прилегающим к диапазону условий.
Gap Lock имеет следующие правила блокировки:
Помните приведенные выше правила. Эти правила нелегко понять. Ниже мы объясним их на примере.
Среда: MySQL, InnoDB, уровень изоляции RR.
Техническая спецификация:
CREATE TABLE `user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`age` int DEFAULT NULL,
`name` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
KEY `age` (`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
данные:
id | age | name |
---|---|---|
1 | 1 | Сяо Мин |
5 | 5 | Сяо Ван |
7 | 7 | Сяо Чжан |
11 | 11 | Сяо Чен |
Перед тестированием давайте взглянем на скрытые пробелы, существующие в таблице пользователей:
Порядок выполнения Транзакции Аи Транзакция Б следующий:
время | Транзакция А | Транзакция Б |
---|---|---|
T1 | begin | begin |
T2 | select * from user where id = 5 for update | |
T3 | вставить в пользовательское значение(3,3,«Маленький черный») ---Без блокировки | |
T4 | вставить в пользовательское значение(6,6,"Сяо Лан") ---без блокировки | |
T5 | commit | commit |
Согласно правилу 4, добавляются блокировки записей, а блокировки пробелов не используются, поэтому блокируется только строка 5 записей.
время | Транзакция А | Транзакция Б |
---|---|---|
T1 | begin | begin |
T2 | выберите * от пользователя, где идентификатор = 3 для обновления --- несуществующие данные | |
T3 | вставить в пользовательское значение(6,6,"Сяо Лан") --- Без блокировки | |
T4 | вставить в пользовательское значение(2,2,"Сяо Хуан") --- блокировка | |
T5 | commit |
Это запрос эквивалентности индекса,По правилу 1 и правилу 5,Диапазон блокировки составляет (1,5 ] , и поскольку последнее значение при перемещении вправо 5 Не соответствует требованиям запроса, Next-Key Lock Перерождается в замок с зазором. То есть окончательный интервал диапазона блокировки равен ( 1,5 )。
время | Транзакция А | Транзакция Б |
---|---|---|
T1 | begin | begin |
T2 | select * from user where id >= 5 and id<6 for update | |
T3 | вставить в пользовательское значение(7,7,"Сяо Чжао") --- блокировка | |
T4 | commit |
Согласно правилу 3, он будет заблокирован до тех пор, пока не появится первое значение, не соответствующее условию, а именно 7, поэтому окончательный диапазон блокировки равен [5, 7].
Фактически, это можно разделить на два этапа. Когда id=5 используется для поиска записи в первый раз, фактически добавляется блокировка пробела (1, 5). И поскольку это запрос, эквивалентный уникальному индексу, он вырождается. в замок ряда и запирает только 5.
использую второй раз id<6 При позиционировании и записи фактически добавляется блокировка зазора ( 5,7 ], поэтому окончательный интервал блокировки равен [ 5,7 ]。
время | Транзакция А | Транзакция Б |
---|---|---|
T1 | begin | begin |
T2 | select * from user where age >= 5 and age<6 for update | |
T3 | вставить в пользовательское значение(8,8,"Сяоцин") --- Без блокировки | |
T4 | вставить в пользовательское значение(2,2,"Сяо Хуан") --- блокировка | |
T5 | commit |
Обратитесь к примеру выше.
Когда age =5 используется для поиска записей в первый раз, добавляется блокировка пробела (1, 5). Это не уникальный индекс, поэтому он не перерастет в блокировку строки. Согласно правилу 5, он будет продолжаться. чтобы соответствовать справа, поэтому в конечном итоге они будут заблокированы. Интервал равен (1, 7].
время | Транзакция А | Транзакция Б |
---|---|---|
T1 | begin | begin |
T2 | select * from user where id = 3 for update | |
T3 | select * from user where id = 4 for update | |
T4 | вставить в пользовательское значение(2,2,"Сяо Хуан") --- блокировка | |
T5 | insert into user значение(4,4,"Сяо Цзы") --- блокировать |
Замки Gap не являются взаимоисключающими, если есть Транзакция. А получил( 1,5 ] Щель между замками, еще одна Транзакция Б еще можно получить ( 1,5 ] щель между замками. В это время может возникнуть проблема взаимоблокировки.
существовать Транзакция Адела сдалась до того, как была снята блокировка пробела, Транзакция B также приобрел замок зазора ( 1,5 ] , то две транзакции находятся в состоянии взаимоблокировки.
время | Транзакция А | Транзакция Б |
---|---|---|
T1 | begin | begin |
T2 | deletet user where age = 6 limt 1 | |
T3 | insert into user значение(7,7,"Сяо Чжао") --- Нетблокировать | |
T4 | ||
T5 | commit | commit |
Согласно правилу 5, интервал блокировки должен быть (5, 7), но поскольку добавлено ограничение 1, цикл завершается после прохождения строки age=6.
Согласно правилу 2, будут заблокированы только те объекты, к которым был осуществлен доступ в процессе поиска, поэтому окончательный интервал блокировки должен составлять: (5, 6].
в этой статье,Мы обсудили правила блокировки для замков с зазором. Блокировки пробелов — важный механизм в MySQL для защиты запросов диапазона и предотвращения одновременных проблем.,Понимание правил блокировки пробелов очень важно для оптимизации производительности библиотеки данных, уменьшения конфликтов данных и повышения одновременной производительности.
Я надеюсь, что эта статья поможет вам глубже понять применение замков с зазорами.,И предоставьте некоторые рекомендации и вдохновение для разработки и оптимизации вашей библиотеки данных. Если у вас есть какие-либо вопросы или вам нужно обсудить дальнейшее,Не стесняйтесь обращаться к нам в любое время.