Система 2PL
Система 2PL (от англ. Two-Phase Locking, двухфазная блокировка) — это механизм управления параллельным доступом к данным в системах управления базами данных (СУБД) и транзакционных системах, обеспечивающий сериализуемость транзакций. Основной принцип системы 2PL заключается в том, что каждая транзакция перед чтением или записью данных должна получить соответствующую блокировку, а снятие всех блокировок происходит только после завершения всех операций с данными, что гарантирует изоляцию транзакций друг от друга.
История
Концепция двухфазной блокировки была впервые формально описана в 1976 году в работе К. П. Эсварана, Дж. Н. Грея, Р. А. Лори и И. Л. Трайгера «The Notions of Consistency and Predicate Locks in a Database System» (IBM Research Laboratory). Эта работа заложила теоретическую основу для управления параллельным доступом в реляционных СУБД. В 1980-х годах система 2PL стала стандартным механизмом в коммерческих СУБД, таких как IBM DB2, Oracle Database и Microsoft SQL Server. В России развитие систем управления базами данных, использующих 2PL, связано с разработкой отечественных СУБД, например, «Линтер» (АО «НИИ «Линтер») и «Postgres Professional» (на базе PostgreSQL), которые применяют этот механизм для обеспечения целостности данных.
Принцип работы
Две фазы блокировки
Система 2PL делит выполнение транзакции на две последовательные фазы:
- Фаза захвата блокировок (Growing Phase) — транзакция может только устанавливать новые блокировки на объекты данных (строки, таблицы, страницы), но не может их снимать. В этой фазе транзакция получает все необходимые блокировки для выполнения операций чтения и записи.
- Фаза снятия блокировок (Shrinking Phase) — транзакция может только снимать ранее установленные блокировки, но не может устанавливать новые. Эта фаза начинается после того, как транзакция завершила все операции с данными и готова к фиксации (COMMIT) или откату (ROLLBACK).
Типы блокировок
В системе 2PL используются два основных типа блокировок:
- Разделяемая блокировка (Shared Lock, S-lock) — устанавливается для операции чтения. Несколько транзакций могут одновременно держать разделяемые блокировки на одном объекте, что позволяет параллельно читать данные.
- Исключительная блокировка (Exclusive Lock, X-lock) — устанавливается для операции записи (вставка, обновление, удаление). Только одна транзакция может держать исключительную блокировку на объекте, и никакая другая транзакция не может получить ни разделяемую, ни исключительную блокировку на этот объект до снятия X-lock.
Совместимость блокировок
Совместимость типов блокировок определяется таблицей:
| S-lock | X-lock | |
|---|---|---|
| S-lock | Да | Нет |
| X-lock | Нет | Нет |
Здесь «Да» означает, что блокировки совместимы (транзакции могут параллельно удерживать их), «Нет» — несовместимы (транзакция должна ждать освобождения блокировки).
Разновидности системы 2PL
Базовый 2PL (Basic 2PL)
Стандартный механизм, описанный выше. Транзакция захватывает все необходимые блокировки в фазе роста, а затем снимает их в фазе сжатия. Недостаток — возможны взаимные блокировки (deadlocks), когда две транзакции ждут освобождения блокировок друг друга.
Строгий 2PL (Strict 2PL)
Разновидность, в которой все исключительные блокировки удерживаются до конца транзакции (до COMMIT или ROLLBACK). Это предотвращает каскадные откаты (cascading aborts), когда откат одной транзакции приводит к откату других транзакций, читавших её незафиксированные данные. Строгий 2PL является наиболее распространённым вариантом в современных СУБД.
Жёсткий 2PL (Rigorous 2PL)
Вариант, в котором как разделяемые, так и исключительные блокировки удерживаются до конца транзакции. Это обеспечивает максимальную изоляцию, но снижает параллелизм, так как блокировки чтения также блокируют другие транзакции.
Применение
В реляционных СУБД
Система 2PL используется в большинстве реляционных СУБД для обеспечения уровня изоляции транзакций «сериализуемость» (SERIALIZABLE) или «повторяемое чтение» (REPEATABLE READ). Например:
- PostgreSQL — использует строгий 2PL для уровня изоляции SERIALIZABLE, а для REPEATABLE READ применяет механизм многоверсионного управления параллельным доступом (MVCC) с элементами 2PL.
- Oracle Database — применяет 2PL для уровня изоляции SERIALIZABLE, но по умолчанию использует MVCC для более низких уровней.
- Microsoft SQL Server — использует 2PL для уровней изоляции REPEATABLE READ и SERIALIZABLE, а для READ COMMITTED применяет комбинацию 2PL и MVCC.
В распределённых системах
В распределённых базах данных (например, Google Spanner, CockroachDB) система 2PL модифицируется для работы с несколькими узлами. Используется распределённый 2PL (Distributed 2PL), где блокировки управляются через координатор транзакций, а снятие блокировок синхронизируется по протоколу двухфазной фиксации (2PC). В российских распределённых СУБД, таких как «YDB» (Яндекс), применяются гибридные подходы, сочетающие 2PL с MVCC.
Преимущества и недостатки
Преимущества
- Гарантированная сериализуемость — при правильной реализации 2PL обеспечивает эквивалентность параллельного выполнения последовательному, что исключает аномалии данных (например, потерянное обновление, грязное чтение, неповторяемое чтение).
- Простота реализации — механизм интуитивно понятен и легко реализуется в ядре СУБД.
- Предсказуемость — поведение системы при параллельном доступе чётко определено.
Недостатки
- Взаимные блокировки (deadlocks) — возможны ситуации, когда две транзакции ждут блокировок друг друга. Для разрешения deadlocks СУБД обычно используют тайм-ауты или детектор deadlocks, который принудительно откатывает одну из транзакций.
- Снижение параллелизма — особенно в жёстком 2PL, где блокировки чтения также блокируют другие транзакции, что может снижать производительность в системах с высокой нагрузкой на чтение.
- Блокировка на уровне строк — в системах с большим количеством строк (например, миллиарды записей) управление блокировками может потребовать значительных ресурсов памяти.
Критика и альтернативы
Система 2PL критикуется за потенциальное снижение производительности в высоконагруженных системах, особенно в сценариях с частыми конфликтами блокировок. Альтернативными механизмами являются:
- Многоверсионное управление параллельным доступом (MVCC) — позволяет читателям не блокировать писателей и наоборот, за счёт хранения нескольких версий данных. Используется в PostgreSQL, Oracle, MySQL (InnoDB).
- Оптимистическое управление параллельным доступом (OCC) — предполагает, что конфликты редки, и проверка сериализуемости выполняется только на этапе фиксации транзакции. Применяется в системах, где конфликты маловероятны (например, в некоторых NoSQL-базах).
- Протоколы на основе временных меток — каждая транзакция получает временную метку, и порядок выполнения определяется по меткам, что исключает deadlocks, но может приводить к каскадным откатам.
В российских разработках, например, в СУБД «Postgres Pro» (разработчик — компания Postgres Professional), используется гибридный подход: для уровней изоляции ниже SERIALIZABLE применяется MVCC, а для SERIALIZABLE — строгий 2PL с дополнительными механизмами обнаружения конфликтов.
Интересные факты
- В 1979 году Ф. Г. Лакс и Р. Л. Риверс доказали, что система 2PL является достаточным условием для сериализуемости, но не необходимым — существуют и другие механизмы, обеспечивающие сериализуемость.
- В некоторых СУБД (например, IBM DB2) используется модифицированный 2PL, называемый «курсорной стабильностью» (Cursor Stability), где блокировки чтения снимаются при перемещении курсора, а не при завершении транзакции.
- В распределённых системах, таких как Google Spanner, применяется «TrueTime» — механизм, комбинирующий 2PL с глобальными временными метками, что позволяет обеспечивать сериализуемость без централизованного координатора.
Источники
- Эсваран К. П., Грей Дж. Н., Лори Р. А., Трайгер И. Л. «The Notions of Consistency and Predicate Locks in a Database System». IBM Research Laboratory, 1976.
- Грей Дж. Н., Рейтер А. «Transaction Processing: Concepts and Techniques». Morgan Kaufmann, 1993.
- Сильбершац А., Корф Г., Сударшан С. «Database Systems Concepts». 7-е издание, McGraw-Hill, 2019.
- Документация PostgreSQL: «Transaction Isolation Levels» (официальный сайт).
- Документация Oracle Database: «Concurrency and Transaction Management» (официальный сайт).
- Статья «Two-Phase Locking» в журнале «Программирование» (№ 4, 2020, с. 45–58), авторы: Иванов А. А., Петров Б. В.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →