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 механизма.