Перейти к содержанию

MVCC, isolation levels и locking

Механизмы · Системы

Тип материала: архитектурный разбор. Схемы и примеры иллюстративные, если не указано иное.

Версии в источниках: PostgreSQL 17, MySQL 8.4, Oracle 19c, Cassandra 5.0, Redis 7.4 и ClickHouse 25.8 либо явно названный сервис.

Механизм

MVCC сохраняет версии и выбирает видимую по snapshot. Locks координируют conflicting operations; MVCC не означает отсутствие locks. Isolation level задаёт допустимые interleavings, а названия уровней не доказывают одинаковую реализацию разных СУБД.

flowchart LR
  T1[Transaction snapshot] --> Versions[Visible row versions]
  T2[Concurrent writer] --> New[New version and locks]
  New --> Detect[Conflict or SSI check]
  Detect --> Commit[Commit if checks succeed]
  Detect --> Retry[Retry whole transaction if aborted]

Операция чтения или записи по шагам

PG17 READ COMMITTED: T1 читает balance=100, T2 commit balance=80, следующий SELECT T1 видит 80. В REPEATABLE READ T1 сохраняет snapshot, но попытка обновить изменённую после snapshot строку может дать serialization failure. xmin/xmax и transaction status участвуют в visibility; это не пользовательские версии.

Консистентность, отказ и восстановление

Write skew: два risk officers видят по одному другому активному и отключают каждый свою строку; row locks разных rows не конфликтуют, invariant нарушен. Нужен общий invariant row lock, подходящий constraint либо SERIALIZABLE с retry. Oracle snapshot serializable и PostgreSQL SSI различаются, как и InnoDB locking/nonlocking RR reads.

Выбор, эксплуатация и ограничения

SELECT FOR UPDATE полезен для заранее известного write set, но длинные transactions увеличивают waits и version retention. Deadlock требует цикла locks; lock order снижает вероятность, timeout не доказывает abort всей бизнес-операции. Повторять транзакцию с тем же idempotency key.

Типичные ошибки проектирования

Считать snapshot isolation serializability; лечить deadlock бесконечным retry; выполнять HTTP под lock. Вопрос: почему reader не видит свой нуженому replica write? MVCC isolation primary и async replica freshness — разные оси.

Вопросы на собеседовании

Как доказать применимость механизма? Назвать invariant, scope, isolation/acknowledgement boundary, версию, допустимые interleavings и процедуру восстановления. Один успешный запрос или статическая диаграмма этого не доказывают.

Практические упражнения

Составьте две-session schedule write skew и исправьте его тремя способами. Для каждого укажите abort/retry и цену contention. Реальный multi-session эксперимент в текущей среде не выполнен.

Дополнительные источники

Политика версий и проверки. Статическая проверка статьи не является runtime/fault verification механизма.