Это второй день моего участия в первом испытании обновлений 2022. Подробную информацию о мероприятии см.:Вызов первого обновления 2022 г.
предисловие
Целью разработки блокировок в базе данных является решение проблем параллелизма.При одновременном доступе к ресурсам база данных должна разумно контролировать правила доступа к ресурсам.
Замок — это структура данных, используемая для реализации этих правил доступа.
При одновременной работе с данными отсутствие блокировок может привести к несогласованности данных, что приведет кобновление потеряно.
Классификация замков
оптимистическая блокировка и пессимистическая блокировка
Оптимистичная блокировка:Более оптимистично смотрите на возможность потери обновлений, сначала подумайте, что потери обновлений не будет, и сравните, когда данные окончательно обновятся.
CREATE TABLE `t` (
`id` int(11) NOT NULL,
`value` int(11) DEFAULT NULL,
`version` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB ;
insert into t values(1,1,1);
select id,value,version from t where id=1;
update t set value=2,version=version+1 where id=1 and version=1;
** Пессимистическая блокировка: ** пессимистично оценивает возможность потери обновления и блокирует его при запросе, чтобы гарантировать, что он не будет использоваться другими транзакциями; это может быть достигнуто с помощью select...fot update.
select * from t where id = 1 for update;
Общая блокировка (блокировка S) и монопольная блокировка (блокировка X)
общий замок(общая блокировка) означает, что несколько транзакций могут совместно использовать ресурсы блокировки, которые обычно добавляются при чтении данных, также известных как блокировки чтения.
select * from t where id = 1 lock in share mode;
эксклюзивный замок(эксклюзивная блокировка, X-блокировка), также известная как блокировка записи (блокировка записи).
После того, как транзакция A добавит X-блокировки к данным, другие транзакции не смогут больше добавлять к данным блокировки, пока транзакция A не снимет X-блокировки с данных.
Увеличивайте, удаляйте и изменяйте данные, чтобы добавить X-блокировки, и используйте для обновления в операторе запроса, чтобы добавить X-блокировки.
S-образный замок | Х замок | |
---|---|---|
S-образный замок | √ | × |
Х замок | × | × |
Различать путем блокировки детализации
глобальная блокировка
Как следует из названия, глобальная блокировка блокирует всю базу данных, после блокировки вся база данных не может выполнять запись в другие транзакции. MySQL предоставляет способ добавить глобальную блокировку чтения, команда:flush tables with read lock
(ФТВРЛ).
-- 加全局读锁
flush tables with read lock;
-- 解锁
unlock tables;
Сценарий использования: полное логическое резервное копирование базы данных.
Но использование глобальной блокировки для резервного копирования имеет следующие проблемы:
- Если вы создаете резервную копию основной базы данных, обновление не может быть выполнено в течение периода резервного копирования, и бизнес в основном должен быть остановлен;
- Если вы создаете резервную копию в ведомой библиотеке, ведомая библиотека не может выполнить двоичный журнал, синхронизированный с главной библиотекой во время резервного копирования, что приведет к задержке ведущий-ведомый.
Если все таблицы во всей базе данных являются механизмом innoDB или другим механизмом хранения, поддерживающим транзакции, вы можете использовать официальный инструмент резервного копирования.mysqldump.
когдаmysqldump
Использовать параметры–single-transaction
Когда данные импортируются, транзакция запускается для обеспечения согласованного представления. Благодаря поддержке MVCC данные могут нормально обновляться во время этого процесса.
Если есть механизм хранения, такой как MyISAM, который не поддерживает транзакции в библиотеке, его нельзя использовать.mysqldump
.
Можно ли использовать set global readonly=true?
недоступноset global readonly=true
Сделайте логические резервные копии после того, как вся библиотека будет доступна только для чтения. Есть две основные причины:
-
read-only
Обычно он используется для различения основной базы данных и резервной базы данных, а также для измененияglobal
Переменная имеет большое влияние и ее не рекомендуется изменять. - Механизм обработки исключений другой: после выполнения команды FTWRL, если клиент аварийно отключится, сервер автоматически снимет глобальную блокировку. Однако после установки для read-ony значения true это будет действовать постоянно.Если клиент аварийно отключится, база данных останется в состоянии только для чтения.
Блокировки на уровне таблицы (табличные блокировки и блокировки MDL)
В MySQL существует два типа блокировок на уровне таблицы: одна — это блокировка таблицы, а другая — блокировка метаданных (MDL).
блокировка стола
lock tables ... read;
lock tables ... write;
-- 解锁
unlock tables;
Накладные расходы на использование блокировок таблиц относительно невелики, блокировки выполняются быстро и взаимоблокировок не возникает, однако степень детализации блокировок велика, вероятность конфликтов блокировок выше, а параллелизм ниже.
Блокировки таблиц устарели в механизме хранения innoDB и используются только в механизмах хранения без поддержки транзакций, таких как MyISAM.
Блокировка метаданных (MDL)
Блокировка метаданных была введена в MySQL 5.5. MDL не нужно добавлять явно. Блокировка чтения MDL добавляется при добавлении, удалении, изменении и запросе данных таблицы, а блокировка записи MDL добавляется при выполнении операции DDL над таблицей.
Блокировка метаданных предназначена для обеспечения согласованности метаданных таблицы, когда несколько транзакций работают с одной и той же таблицей.
В чем проблема, если нет блокировки метаданных?
-
Проблемы с изоляцией транзакций:Например, при уровне изоляции повторяющегося чтения во время двух запросов сеанса A сеанс B изменяет структуру таблицы, и результаты двух запросов будут несогласованными, что не может соответствовать требованиям повторяемого чтения.
-
Проблема с синхронизацией данных:Например, когда сеанс A выполняет несколько операторов обновления, другой сеанс B изменяет структуру таблицы и отправляет ее первой, что приведет к повторному выполнению резервной базы данных первой при повторном выполнении.
alter table
заявление, повторитьupdate
Ошибка копирования возникает при выполнении инструкции.
Блокировки чтения MDL не являются взаимоисключающими, поскольку таблица может поддерживать несколько транзакций для одновременного добавления, удаления, изменения и запроса.Блокировки чтения и записи, а также блокировки записи и записи являются взаимоисключающими для обеспечения безопасности таблицы. изменения структуры.
При выполнении DDL для таблицы все добавления, удаления, изменения и проверки блокируются. Поэтому вы должны быть очень осторожны при изменении или добавлении полей в поля таблицы.
Как правило, мы уделяем особое внимание DDL для масштабов больших данных, чтобы не влиять на онлайн-бизнес. Однако будьте осторожны при выполнении операций DDL с небольшими таблицами, например в следующих сценариях:
-
Сначала запускается транзакция A, затем к таблице t добавляется блокировка чтения MDL;
-
Затем транзакция B хочет добавить поля в таблицу t, что требует получения блокировки записи MDL, но поскольку транзакция A еще не зафиксирована, блокировка чтения MDL не снята, поэтому транзакция B будет заблокирована;
-
Неважно, блокируется ли только транзакция B, в лучшем случае DDL выполняется позже; но все добавления, удаления и изменения в таблице t после этого будут заблокированы, в результате чего таблица t не сможет выполнять какие-либо операции чтения и записи.
блокировка намерения
Намеренная блокировка — это блокировка, добавляемая на уровне таблицы, которая делится на преднамеренную совместную блокировку (блокировку IS) и намеренную монопольную блокировку (блокировку IX).
Блокировка намерения, как следует из названия, указывает, какой тип операции необходимо выполнить следующей.
Преднамеренная общая блокировка (IS): при подготовке к добавлению S-блокировки к данным таблицы необходимо сначала получить блокировку IS для таблицы.
Преднамеренная монопольная блокировка (IX): при подготовке к добавлению блокировки X к данным таблицы необходимо сначала получить блокировку IX таблицы.
Причина существования преднамеренных блокировок, так в приведенном выше примере:
Еще одна основная причина появления блокировок по намерению — достижение более высокой эффективности при поддержке блокировок с разной степенью детализации.
Транзакция A добавляет блокировку строки к строке данных в таблице T. В это время транзакции B необходимо добавить блокировку таблицы к таблице T, но перед добавлением ей необходимо проверить, удерживают ли другие транзакции блокировку X таблицы. блокировать;
Транзакция B и замок через все строки в таблице T, так что судить неэффективно, отнимает много времени.
Поскольку блокировка намерения является блокировкой на уровне таблицы, прежде чем транзакция A обновит данные и добавит блокировку строки, база данных автоматически добавит блокировку IX на уровне таблицы. Затем, когда транзакции B необходимо получить блокировку X, она только нужно проверить уровень таблицы нет.Есть блокировка IX.Если есть блокировка IX, это означает, что другая транзакция в данный момент выполняет операцию записи в таблицу или данные в таблице, и блокировка не может быть успешно добавлен.
блокировка строки
Блокировка строк в MySQL реализована на уровне движка хранилища, и не все движки его поддерживают, например, в движке MyISAM нет блокировки строк.
Блокировка строки, как следует из названия, заключается в добавлении блокировки к строке данных. Например, если транзакция A хочет обновить строку данных, сначала добавляется блокировка строки, а затем транзакции B также необходимо обновить строку. Перед обновлением он должен дождаться, пока транзакция A снимет блокировку строки.
Время блокировки и разблокировки блокировок строк
В транзакциях InnoDB блокировки строк добавляются по мере необходимости, но они не снимаются сразу, когда в них нет необходимости, а освобождаются по завершении транзакции. ЭтоПротокол двухфазной блокировки.
begin;
update t set value = value + 1 where id = 1;
update t set value = value + 1 where id = 2;
begin ;
update t set value = value + 1 where id = 1;
Поэтому, если вам нужно заблокировать несколько строк в транзакции, поместите блокировки, которые с наибольшей вероятностью вызовут конфликты блокировок и с наибольшей вероятностью повлияют на параллелизм, как можно дальше.
гэп замок
Блокировка пробела блокирует разрыв между двумя значениями.
Все мы знаем, что появление каждой технологии должно решить определенную проблему, так какую проблему может решить блокировка разрыва?
Предположим, что нет блокировки промежутка, что произойдет, давайте посмотрим на следующий пример, следующий контент находится под предпосылкой уровня изоляции повторяемого чтения.
Есть следующая таблица:
CREATE TABLE `t` (
`id` int(11) NOT NULL,
`c` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `c` (`c`)
) ENGINE=InnoDB;
insert into t values(0,0,0),(5,5,5),(10,10,10),(15,15,15),(20,20,20);
Предположим, мы хотим выполнить следующий SQL, как заблокировать и разблокировать?
begin;
select * from t where d=5 for update;
commit;
Легче понять, что этот оператор попадет в строку с d=5 и соответствующий первичный ключ с id=5, поэтому после выполнения оператора select к строке с id=5 будет добавлена блокировка записи, и из-за к протоколу двухфазной блокировки, блокировка записи будет снята при выполнении оператора фиксации.
Поскольку в поле d нет индекса, этот оператор запроса выполнит полное сканирование таблицы. Тогда будут ли заблокированы остальные 5 строк записей, которые сканируются, но не соответствуют условиям?
Выполнено 3 запроса в транзакции A, на всем протяженииfor update
Получает блокировку записи и является текущим чтением.
Если предположить, что заблокирована только строка с id=5, результаты выполнения трех запросов будут следующими:
- Q1 возвращает результат в виде (5,5,5);
- Q2 возвращает результат как (0,0,5),(5,5,5);
- Q3 возвращает результат как (0,0,5)(1,1,5)(5,5,5);
Затем данные с id=1 запрашиваются в результате Q3, и это явление называется «фантомное чтение».
Это прерывает транзакцию A вselect * from t where d=5 fot update;
Семантика блокировки всех данных с d=5.
Во-вторых, будут проблемы с согласованностью данных.
Если в транзакции Bbinlog
Получение резервной базы данных и ее выполнение дадут разные результаты.
Фактическая проверка, результат не только блокирует строку с id=5, но и блокирует все промежутки. Это гарантирует, что никакие новые данные не могут быть вставлены.
блокировка следующего ключа
Блокировка пробела и блокировка строки в сочетанииnext-key lock, каждыйnext-key lockЭто передний интервал открытия и задний интервал закрытия. То есть после инициализации нашей таблицы t, если мы используемselect * from t where for update
Для блокировки всех записей во всей таблице формируется 7 записейnext-key lock, соответственно (-∞,0], (0,5], (5,10], (10,15], (15,20], (20, 25], (25, +супремум)).
Назначение гэп-блокировок и временных блокировок построения состоит в том, чтобы решить проблему повторяющихся операций чтения.Если они находятся на уровне фиксации чтения, и гэп-блокировки, и временные блокировки построения потерпят неудачу.
Правила блокировки
Правила блокировки данных в MySQL можно разделить на следующие три типа:
два принципа
- Базовой единицей блокировки является блокировка следующего ключа.
- Объекты, к которым был получен доступ в процессе поиска, будут заблокированы
две оптимизации
- Для эквивалентного запроса по индексу, когда уникальный индекс заблокирован, блокировка следующего ключа вырождается в блокировку строки.
- Для эквивалентного запроса по индексу, при перемещении вправо и последнем значении, не удовлетворяющем эквивалентному условию, блокировка следующего ключа вырождается в блокировку пробела.
Жук
- Запросы диапазона на доступ к уникальным индексам до первого значения, не удовлетворяющего условию
Взаимоблокировки и обнаружение взаимоблокировок
Что такое тупик?
В системе, поддерживающей параллельные операции, разные потоки циклически зависят от ресурсов, а потоки удерживают ресурсы, необходимые друг другу, что приводит к тому, что потоки входят в бесконечное состояние ожидания, которое называется взаимоблокировкой.
В базе данных из-за наличия механизма блокировки это также приведет к взаимоблокировке. Например:
- Транзакция A сначала получает блокировку строки с id=1, а затем транзакция B получает блокировку строки с id=2;
- Затем транзакция A хочет получить блокировку строки с id=2 и обнаруживает, что она удерживается транзакцией B и блокируется;
- Транзакция B хочет получить блокировку строки с id=1 и обнаруживает, что она удерживается транзакцией A и блокируется;
- Обе транзакции входят в состояние взаимоблокировки.
Когда возникает тупик, есть две стратегии обработки:
- Перейдите непосредственно к ожиданию истечения времени ожидания соединения, период ожидания может быть пройден
innodb_lock_wait_timeout
настраивать. - Инициировать обнаружение тупика и активно откатывать транзакцию в тупике после обнаружения тупика, позволяя другим транзакциям выполняться нормально. установить параметр
innodb_deadlock_detect
Установить какon
, указывая на то, что обнаружение взаимоблокировок включено.
Писать не легко, мне нужен небольшой положительный отзыв, если вам понравилось, ставьте лайк~
Рекомендуемые статьи в прошлом:
Избавьтесь от BeanUtils, MapStruct - YYDS
Интервьюер попросил меня спроектировать кэш LRU, и результат...
Как бороться с повторяющимися зависимостями в maven
Ган! Есть так много вещей, которые следует учитывать при создании системы коротких ссылок.
Колонна Блэка:
Xiaohei сказал сборник качественных статей
[Следуйте за Xiaohei, чтобы изучить режим дизайна]
【Серия параллельного программирования】
Я Сяо Хей, программист, который «выслеживает» Интернет.
Текущая вода не соревнуется за первое, а говорить дорого