Транзакции и MVCC
AngaraBase обеспечивает конкурентный доступ к данным через MVCC (Multi-Version Concurrency Control). Транзакции гарантируют атомарность изменений, а MVCC позволяет читателям и писателям работать одновременно без взаимных блокировок.
Основы транзакций
Управление транзакциями
BEGIN; -- начать явную транзакцию
SAVEPOINT sp1; -- создать точку сохранения
ROLLBACK TO SAVEPOINT sp1; -- откатить до точки сохранения
COMMIT; -- зафиксировать транзакцию
ROLLBACK; -- откатить всю транзакцию
Autocommit
По умолчанию AngaraBase работает в режиме autocommit: каждый отдельный SQL-оператор выполняется как самостоятельная транзакция. Если оператор завершается успешно — результат фиксируется автоматически, при ошибке — откатывается.
Для операций, затрагивающих несколько строк или таблиц, используйте явные транзакции (BEGIN / COMMIT),
чтобы объединить изменения в единую атомарную единицу.
MVCC: версионирование строк
Ключевая идея MVCC — читатели не блокируют писателей, писатели не блокируют читателей. Это достигается за счёт хранения нескольких версий каждой строки.
Метаданные версий
Каждая версия строки содержит два служебных поля:
| Поле | Назначение |
|---|---|
created_commit | Epoch (commit timestamp), при котором версия была создана |
deleted_commit | Epoch, при котором версия была помечена как удалённая (∞ для активных версий) |
Правило видимости
Версия строки видна транзакции со snapshot S, если выполняются оба условия:
created_commit <= S— версия создана до или в момент snapshot- Версия не удалена, или
deleted_commit > S— удаление произошло после snapshot
Операции записи
- INSERT — создаёт новую версию строки с
created_commit= текущий epoch - UPDATE — не меняет строку на месте. Вместо этого: помечает текущую версию как удалённую
(
deleted_commit= текущий epoch) и создаёт новую версию с обновлёнными данными - DELETE — помечает версию как удалённую (
deleted_commit= текущий epoch)
Уровни изоляции
Каждая транзакция получает snapshot — фиксированное представление данных на определённый момент времени.
READ COMMITTED (по умолчанию)
Snapshot обновляется перед каждым оператором. Транзакция видит все данные, зафиксированные до начала текущего оператора. Это рекомендуемый уровень изоляции для большинства задач.
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
REPEATABLE READ
Snapshot фиксируется в момент BEGIN и не меняется до конца транзакции. Все операторы внутри транзакции видят одно и то же состояние данных.
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SERIALIZABLE
С версии 0.6.4.4 AngaraBase реализует полноценный SERIALIZABLE (SSI) уровень изоляции.
В режиме SERIALIZABLE аномалии write skew и phantoms предотвращаются через
механизм SIREAD-блокировок и отслеживание rw-антизависимостей.
Транзакции, нарушающие сериализуемость, прерываются с кодом 40001.
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
Блокировки
Операции чтения
Чтение использует MVCC snapshot и не требует блокировок. Читатель никогда не ждёт писателя и наоборот.
Операции записи (Lock-Free DML)
Писатели используют атомарные операции (Compare-And-Swap) для установки версий на уровне строк, что обеспечивает lock-free бесконфликтные изменения. Блокировки в классическом виде больше не удерживаются.
DDL-операции
Операции изменения схемы (CREATE TABLE, ALTER TABLE, DROP TABLE) захватывают table-level locks на время выполнения.
Обнаружение deadlock
AngaraBase обнаруживает взаимные блокировки (deadlock) с помощью:
- Timeout — если транзакция ожидает блокировку дольше заданного порога, она прерывается
- Victim selection — при обнаружении цикла система выбирает транзакцию-жертву для отката
- Deterministic lock ordering — внутренняя стратегия упорядочивания блокировок для снижения вероятности deadlock
Сборка мусора (AngaraGC)
Со временем в хранилище накапливаются старые версии строк, которые больше не видны ни одной активной транзакции. Подсистема AngaraGC отвечает за их очистку.
Механизм работы
- GC watermark — вычисляется как минимальный snapshot среди всех активных транзакций:
min(active_snapshots) - Версии строк с
deleted_commit < watermarkбезопасны для удаления — ни одна активная транзакция не может их увидеть - Очистка выполняется фоновым процессом без остановки обработки запросов
- Bounded slices — GC обрабатывает данные порциями фиксированного размера, чтобы не вызывать всплески задержки
- Epoch Reaper — фоновый процесс (начиная с версии 0.6.5.24), который предотвращает зависание GC watermark из-за разорванных соединений или зависших сессий.
Отличие от PostgreSQL
В AngaraBase нет autovacuum в привычном понимании. Используется гибридный дизайн с epoch-based watermark (как в Oracle/InnoDB), что позволяет точнее контролировать момент очистки.
Рекомендации
- Используйте READ COMMITTED (уровень по умолчанию) для большинства рабочих нагрузок
- Избегайте долгоживущих транзакций — они удерживают GC watermark и не позволяют очистить старые версии строк, что увеличивает потребление дискового пространства
- При использовании REPEATABLE READ помните о возможности write skew. Если нужна строгая сериализуемость,
используйте явные блокировки (
SELECT ... FOR UPDATE)
MVCC state при crash recovery
При перезапуске после аварийного завершения AngaraBase восстанавливает состояние MVCC из transaction log (WAL).
Что восстанавливается
- Committed transactions — транзакции, которые успели записать COMMIT в WAL
- Aborted transactions — незавершённые транзакции помечаются как aborted
- MVCC visibility — информация о том, какие версии строк видны для каждого commit epoch
- Transaction counters — текущий commit epoch и другие счётчики
Процесс восстановления
- WAL scan — сканирование файлов transaction log в хронологическом порядке
- MVCC replay — восстановление in-memory структур MVCC из записей в WAL
- Cleanup — пометка незавершённых транзакций как aborted
Ограничения
- Backend requirement: восстановление MVCC работает только с
transaction_log.backend = "file_bin" - Memory rebuild: MVCC state восстанавливается в памяти, что может занять время при большом объёме WAL
- Read-your-writes: сразу после restart незавершённые транзакции не видны (помечены как aborted)
Мониторинг восстановления
-- Проверить режим восстановления
SELECT recovery_mode FROM sys.identity;
-- Проверить состояние системы после recovery
SELECT txn_commit_epoch_current FROM sys.health;
Возможные значения recovery_mode:
"normal"— обычный старт без восстановления"crash_recovery"— восстановление после аварийного завершения"forced_takeover"— принудительный захват instance lease
Связанные разделы
- Storage engine — устройство хранилища и формат страниц
- Instance Lifecycle — жизненный цикл инстанса и crash recovery
- Crash Recovery — операционные процедуры восстановления
- Справочник SQL — синтаксис SQL-операторов