Сейчас уже не вспомню, какого черта я полез искать разницу между "lock" и "latch" — кажется, кто-то из студентов при переводе на английский использовал эти слова взаимозаменяемо. Как бы то ни было, я положил в закладки себе эту статью, чтобы обязательно подготовить ее для ИТ-переводчиков (т.е. с указанием английских терминов). Собственно, вот, ее перевод ниже. Статья небольшая и базовая, спецы по СУБД в ней ничего нового для себя не найдут.
В этом руководстве мы разберем понятия блокировок [locks]
и защёлок [latches]
в базах данных, а также основные различия между ними. В конце поделимся некоторыми рекомендациями и лучшими практиками по использованию этих механизмов.
Управление параллелизмом в системах баз данных
Управление параллелизмом — это система механизмов, используемая для поддержания целостности и производительности систем баз данных, когда несколько транзакций одновременно обращаются к данным и изменяют их. Даже при параллельном выполнении нескольких транзакций эта система гарантирует, что база данных остаётся в согласованном состоянии.
Очевидно, что когда [при правильной настройке - прим. пер.] несколько транзакций выполняются параллельно, СУБД могут эффективнее использовать доступные ресурсы и обрабатывать больший объём запросов одновременно.
Что такое блокировки?
Блокировки служат механизмами синхронизации для управления параллелизмом. Они регулируют доступ к общим элементам данных и гарантируют согласованность данных при параллельных транзакциях:

Блокировка базы данных
Блокировка позволяет транзакциям получать доступ на чтение или запись к данным, обеспечивая предотвращение конфликтов и соблюдение изоляции.
Типы блокировок
Типы блокировок и их гранулярность зависят от требований управления параллелизмом, шаблонов доступа к данным и уровней изоляции в системах баз данных. Часто используемые блокировки в базах данных включают разделяемые [shared locks]
, эксклюзивные [exclusive lock]
и блокировки обновления [update lock]
.
Разделяемая блокировка позволяет нескольким транзакциям параллельно читать элемент данных. В контексте баз данных разделяемые блокировки обычно называют «блокировками чтения» [read lock]
.
Эксклюзивная блокировка предоставляет эксклюзивный доступ на запись к элементу данных. Когда транзакция получает эксклюзивную блокировку на элемент данных, она запрещает другим транзакциям читать или записывать этот элемент. Эксклюзивные блокировки не могут сосуществовать с другими разделяемыми или эксклюзивными блокировками. Таким образом, мы гарантируем отсутствие конфликтов и обеспечиваем эксклюзивный доступ к рассматриваемому элементу данных.
Блокировка обновления служит промежуточной блокировкой, расположенной между разделяемой и эксклюзивной блокировками. Её цель — обеспечить параллельное чтение, предотвращая конфликтующие обновления. Когда транзакция владеет блокировкой обновления на элементе данных, она разрешает другим транзакциям получать разделяемые блокировки для чтения, но запрещает им получать эксклюзивные блокировки.
Мы используем блокировки обновления для защиты от возникновения аномалии «перекоса записи» [write skew], которая возникает, когда несколько транзакций параллельно обновляют одни и те же данные и может привести к некорректным результатам.
Что такое защёлки?
Защёлка — это механизм синхронизации, используемый для управления параллельным доступом и обеспечения целостности данных. СУБД обычно применяют защёлки для активной защиты общих ресурсов, таких как структуры данных или буферы, от параллельного доступа несколькими транзакциями или потоками.
Конструкция защёлки обеспечивает быстрый захват [acquisition]
и освобождение [release]
, обычно происходящие в течение одного цикла процессора, что делает её идеально подходящей для защиты часто используемых структур данных в СУБД:

Защёлки могут работать в совместном [shared latch]
и монопольном [exclusive latch]
режимах. Совместные защёлки разрешают параллельный доступ на чтение нескольким транзакциям или потокам. Монопольные защёлки предоставляют эксклюзивный доступ на запись, предотвращая одновременные модификации.
Захват защёлки
Когда поток или процесс должен получить доступ к общему ресурсу, защищённому защёлкой, он запрашивает защёлку, вызывая соответствующую функцию в СУБД.
Если защёлка недоступна, поскольку её удерживает другая транзакция или поток, запрашивающая сторона может перейти в состояние активного ожидания [spin-waiting state] и периодически опрашивать защёлку до тех пор, пока она не станет доступной. Активное ожидание помогает минимизировать накладные расходы на переключение контекста, однако во время ожидания оно потребляет циклы процессора.
Освобождение защёлки
После завершения операции с общим ресурсом поток освобождает защёлку, позволяя другим потокам её захватить. Защёлка обычно освобождается через вызов соответствующей функции в СУБД.
При освобождении защёлки СУБД уведомляет ожидающие потоки о её доступности. Затем ожидающие потоки начинают конкурировать друг с другом, чтобы захватить защёлку и продолжить выполнение своих операций. Поскольку защёлки регулярно захватываются и освобождаются, разработчики обычно проектируют эти механизмы так, чтобы они работали быстро и легко.
Различия между блокировками и защёлками
Блокировки и защёлки представляют собой механизмы синхронизации в системах баз данных, но выполняют различные задачи и работают на разных уровнях системы:
Блокировки |
Защёлки |
Работают на более высоком уровне детализации; захватываются на общих ресурсах, таких как таблицы, строки или страницы; |
Захват происходит в структурах данных нижнего уровня, таких как буферы и страницы данных; |
Используются для управления параллелизмом в многопользовательской системе баз данных; |
Используются для синхронизации в однопоточной среде; |
Поддерживают различные режимы, такие как разделяемые ( |
Обычно имеют бинарную природу и разрешают только эксклюзивный ( |
Обычно удерживаются в течение более длительного времени; |
Удерживаются в течение более коротких периодов; |
Более сложны и требуют дополнительного учёта; |
Операции захвата и освобождения защёлок обычно лёгки и экономичны по ресурсам. |
Рекомендации и лучшие практики
Выбор между блокировками и защелками определяется архитектурой и схемой СУБД, конкретными требованиями системы и защищаемыми ресурсами.
Блокировки обычно применяются, когда нужно обеспечить корректность атомарных изменений при обновлении остатков на складе или на банковском счете.
Когда для выполнения операции нужно включить ограничение по внешнему ключу или каскад обновлений/удалений, то чтобы обеспечить целостность ссылок, используют блокировки. Они предотвращают расхождение данных и гарантируют их синхронизацию при параллельных операциях.
Защёлки же — активные участницы сценариев сценариях управления памятью, где они помогают выделять или освобождать блоки памяти.
На этапах оптимизации и выполнения запросов защёлки помогают защищать планы доступа [access plan
, не путать с query plan/query execution plan
– план выполнения запроса], контексты выполнения и другие внутренние структуры, имеющих отношение к обработке запросов.
Оптимизация использования блокировок и защёлок для повышения производительности
Применение блокировок и защёлок требует тщательного учёта требований приложения, характеристик общих ресурсов и специфического поведения СУБД.
Конфликты возникают, когда несколько потоков или процессов одновременно пытаются получить доступ к одной и той же блокировке или защёлке, что приводит к задержкам и снижению параллелизма. Чтобы минимизировать конфликты, следует избегать использования единой блокировки или защёлки для всей структуры данных.
Разделение структуры данных на более мелкие единицы позволяет обеспечить параллельный доступ, снижая конфликты между множеством потоков. Долгое удержание блокировок или защёлок пагубно влияет на параллелизм и производительность. И наоборот — своевременный захват и освобождение общих ресурсов улучшает параллелизм, снижает частоту конфликтов и повышает общую производительность.
Укрупнение или эскалация блокировок [lock escalation]
— это техника, используемая СУБД для автоматического преобразования чрезмерно гранулированных блокировок в более общие для снижения накладных расходов. Например, СУБД может уменьшить количество блокировок, преобразовав несколько построчных блокировок в блокировку на уровне таблицы.
На этом содержательная часть статьи заканчивается, поэтому прощаюсь с вами и я. Надеюсь, вы нашли тут свою крупицу пользы.