Управление конкурентным доступом в базе данных MySQL

Задача управления конкурентным доступом возникает в тот момент, когда несколь­ким запросам необходимо одновременно изменить данные. В рамках текущих моих блогов оговорим, что MySQL должна решать эту задачу на двух уровнях: сервера и под­системы хранения данных. Управление конкурентным доступом — это обширная тема, которой посвящено множество теоретических исследований. Мы же просто представим обзор того, что MySQL делает с конкурентными запросами на чтение и запись, чтобы вы смогли получить общее представление об этой теме, а это, в свою очередь, позволит разобраться в данном материале.


Оглавление статьи[Показать]


В качестве примера будем использовать ящик электронной почты в системе UNIX. Классический файл формата mbox очень прост. Все сообщения в почтовом ящике mbox расположены одно за другим, так что читать и анализировать почтовые со­общения очень просто. Это также существенно упрощает доставку почты: достаточно добавить новое сообщение в конец файла.

Но что происходит, когда два процесса пытаются одновременно поместить сообще­ния в почтовый ящик? Очевидно, что чередование строк этих сообщений приведет к повреждению файла. Чтобы предотвратить это, правильно работающие почтовые системы используют блокировку. Если клиент пытается отправить новое сообщение в тот момент, когда почтовый ящик заблокирован, ему придется подождать, пока он не сможет сам использовать блокировку, чтобы отправить сообщение.

Эта схема довольно хорошо работает, но не поддерживает конкурентный доступ. По­скольку в любой момент времени только один процесс может изменять содержимое почтового ящика, такой подход создает проблемы при работе с большими почтовыми ящиками.

 

Блокировки чтения/записи в MySQL

Чтение из почтового ящика не вызывает таких проблем. Ничего страшного, если несколько клиентов одновременно считывают информацию из одного и того же по­чтового ящика. Раз они не вносят изменений, ничего плохого случиться не должно. Но что произойдет, если кто-нибудь попытается удалить сообщение № 25 в тот момент, когда программы читают письма из почтового ящика? Возможны различ­ные варианты развития ситуации, но программа чтения может получить почтовый ящик в поврежденном или неструктурированном виде. Поэтому для обеспечения безопасности даже чтение информации из почтового ящика требует определенных предосторожностей.

Если представить, что почтовый ящик — это таблица базы данных, а каждое почтовое сообщение — строка, легко увидеть, что и в этом контексте актуальна та же проблема. Во многих смыслах почтовый ящик является простой таблицей базы данных. Моди­фикация строк в такой базе очень похожа на удаление или изменение содержимого сообщений в файле почтового ящика.

У классической задачи управления конкурентным доступом довольно простое реше­ние. В системах, которые имеют дело с конкурентным доступом для чтения/записи, чаще всего реализуется система блокирования, содержащая два типа блокировок. Обычно их называют разделяемыми блокировками и монопольными блокировками, или блокировками чтения и блокировками записи.

Не вдаваясь в подробности технологии блокирования, данную концепцию можно описать следующим образом. Блокировки чтения ресурса являются разделяемыми или взаимно неблокирующими: множество клиентов могут производить считыва­ние из ресурса в одно и то же время, не мешая друг другу. Блокировки записи, напротив, являются эксклюзивными. Другими словами, они исключают возможность установки блокировки чтения и других блокировок записи, поскольку единственной безопасной политикой является наличие только одного клиента, выполняющего запись в данный момент времени, и предотвращение во время этого всех операций чтения.

В базах данных блокировки происходят постоянно: MySQL запрещает одному кли­енту считывать данные, когда другой клиент их изменяет. Управление блокировками осуществляется внутри СУБД в соответствии с принципами, которые достаточно прозрачны для клиентов.

 

Детальность блокировок

Одним из способов улучшения конкурентного доступа к разделяемому ресурсу является увеличение избирательности блокировок. Вместо того чтобы блокиро­вать весь ресурс, можно заблокировать только ту его часть, которая содержит из­меняемые данные. Еще лучше заблокировать лишь тот фрагмент данных, который будет изменен. Минимизация объема данных, которые вы блокируете в каждый момент времени, позволяет одновременно выполнять несколько изменений одного и того же ресурса, если эти операции не конфликтуют друг с другом.

Определенная проблема возникает из-за того, что блокировки потребляют ресурсы. Каждая операция блокирования — получение возможности блокировки, проверка того, можно ли применить блокировку, снятие блокировки и т. п. — влечет за собой издержки. Если система тратит слишком много времени на управление блокиров­ками вместо того, чтобы расходовать его на сохранение и извлечение данных, то это может повлиять на производительность.

Стратегия блокирования является компромиссом между неизбежностью издер­жек на реализацию блокировок и безопасностью данных, причем подобный компромисс влияет на производительность. Большинство коммерческих серверов баз данных не предоставляют особого выбора: вы получаете возможность блокировки таблиц на уровне строки, при этом нередко в сочетании с множеством сложных способов обеспечить хорошую производительность при большом количестве блоки­ровок.

 

MySQL также предоставляет выбор. Подсистемы хранения данных MySQL мо­гут реализовывать собственные стратегии блокировки и уровни детализации блокировок. Управление блокировками является очень важным решением при проектировании подсистем хранения данных. Установка детализации на опреде­ленном уровне в ряде случаев может улучшить производительность, но сделать эту подсистему менее подходящей для других целей. Поскольку MySQL пред­лагает несколько подсистем хранения данных, нет необходимости принимать единственное решение на все случаи жизни. Рассмотрим две наиболее важные стратегии блокировок.

 

Табличные блокировки

Табличная блокировка является базовой стратегией блокировки в MySQL. Кроме того, у нее самые низкие издержки. Табличная блокировка аналогична рассмо­тренным ранее блокировкам почтового ящика — блокируется вся таблица. Когда клиент хочет сделать запись в таблицу (вставку, удаление, обновление и т. п.), он получает блокировку на запись для всей таблицы. Это предотвращает все остальные операции чтения и записи. Когда никто не выполняет запись, любой клиент может получить блокировку на чтение, которая не конфликтует с другими подобными блокировками.

У табличных блокировок есть вариации для обеспечения высокой производитель­ности в различных ситуациях. Например, табличные блокировки READ LOCAL разрешают выполнять некоторые типы параллельных операций записи. Кроме того, блокировки записи имеют более высокий приоритет, чем блокировки чтения. По­этому запрос блокировки записи будет помещен в очередь перед уже находящими­ся там запросами блокировки чтения (блокировки записи могут отодвигать в очере­ди блокировки чтения, а блокировки чтения не могут отодвигать блокировки записи).

Подсистемы хранения также могут управлять собственными блокировками.

MySQL использует множество блокировок, эффективных на уровне таблиц, для раз­личных целей. Например, для таких операторов, как ALTER TABLE, сервер применяет табличную блокировку вне зависимости от подсистемы хранения данных.

 

Построчные блокировки

Построчные блокировки обеспечивают лучшее управление конкурентным доступом (и влекут максимальные издержки). Блокировка на уровне строк доступна, в частно­сти, в подсистемах хранения InnoDB и XtraDB. Построчные блокировки реализуются подсистемами хранения данных, а не сервером (если нужно, еще раз взгляните на рис. 1. из поста об архитектуре MySQL). Сервер ничего не знает о блокировках, реализованных подсистемой хране­ния данных, и, как вы увидите далее, все подсистемы хранения данных реализуют блокировки по-своему.

 

Вас заинтересует / Intresting for you:

Модель развития базы данных My...
Модель развития базы данных My... 1416 просмотров Ирина Светлова Thu, 10 Jan 2019, 12:29:03
Обзор версий MySQL - какой рел...
Обзор версий MySQL - какой рел... 10611 просмотров Ирина Светлова Fri, 05 Feb 2021, 17:19:41
Выбор оптимальных типов данных...
Выбор оптимальных типов данных... 9760 просмотров Валерий Павлюков Sun, 27 Oct 2019, 15:24:19
Подсистемы (движки) хранения в...
Подсистемы (движки) хранения в... 4613 просмотров Дэйзи ак-Макарова Wed, 04 Aug 2021, 18:11:43
Войдите чтобы комментировать