Открыть сервис

Система 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 делит выполнение транзакции на две последовательные фазы:

  1. Фаза захвата блокировок (Growing Phase)транзакция может только устанавливать новые блокировки на объекты данных (строки, таблицы, страницы), но не может их снимать. В этой фазе транзакция получает все необходимые блокировки для выполнения операций чтения и записи.
  2. Фаза снятия блокировок (Shrinking Phase) — транзакция может только снимать ранее установленные блокировки, но не может устанавливать новые. Эта фаза начинается после того, как транзакция завершила все операции с данными и готова к фиксации (COMMIT) или откату (ROLLBACK).

Типы блокировок

В системе 2PL используются два основных типа блокировок:

  • Разделяемая блокировка (Shared Lock, S-lock) — устанавливается для операции чтения. Несколько транзакций могут одновременно держать разделяемые блокировки на одном объекте, что позволяет параллельно читать данные.
  • Исключительная блокировка (Exclusive Lock, X-lock) — устанавливается для операции записи (вставка, обновление, удаление). Только одна транзакция может держать исключительную блокировку на объекте, и никакая другая транзакция не может получить ни разделяемую, ни исключительную блокировку на этот объект до снятия X-lock.

Совместимость блокировок

Совместимость типов блокировок определяется таблицей:

S-lockX-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 →