Gymterview
middle

Что такое MVCC и как он реализован в PostgreSQL?

MVCC (Multi-Version Concurrency Control) — механизм управления конкурентным доступом, при котором каждая транзакция видит свой «снимок» (snapshot) данных. Главный принцип: читатели не блокируют писателей, а писатели не блокируют читателей.

Аналогия из жизни: MVCC — это как Google Docs с историей версий. Каждый пользователь видит свою версию документа на момент открытия, а изменения других пользователей появляются только после «обновления страницы» (нового оператора или транзакции).

Реализация в PostgreSQL

Каждая строка (tuple) содержит скрытые системные столбцы:

  • xmin — ID транзакции, которая создала эту версию строки
  • xmax — ID транзакции, которая удалила (или обновила) эту версию (0, если строка «живая»)
  • ctid — физический адрес строки на странице

Что происходит при UPDATE

  1. Текущая версия строки не изменяется — у неё устанавливается xmax равным ID текущей транзакции
  2. Создаётся новая версия строки с изменёнными данными, xmin = ID текущей транзакции
  3. Обе версии физически присутствуют в таблице
Пример
-- Наглядно: смотрим системные столбцы
SELECT xmin, xmax, ctid, * FROM accounts WHERE id = 1;
-- Результат: xmin=100, xmax=0, ctid=(0,1), id=1, balance=5000

-- После UPDATE в другой транзакции (txid=200):
-- Старая версия: xmin=100, xmax=200, ctid=(0,1)
-- Новая версия:  xmin=200, xmax=0,   ctid=(0,5)

Видимость строк

Транзакция видит строку, если:

  • xmin зафиксирована (committed) и < ID текущей транзакции (или это она сама)
  • xmax не установлен (0) или не зафиксирован, или > ID текущей транзакции

Последствия MVCC

  • При обновлении и удалении создаются «мёртвые» (dead) версии, которые занимают место
  • Необходим процесс VACUUM для очистки мёртвых версий
  • Индексы также содержат ссылки на все версии строк
  • Таблицы могут «раздуваться» (table bloat) без регулярного VACUUM

Преимущества MVCC

  • Читатели не блокируют писателей — высокая производительность при конкурентном доступе
  • Консистентные snapshot-чтения без блокировок
  • Это фундамент всех уровней изоляции в PostgreSQL

На собеседовании: MVCC — один из самых частых вопросов по PostgreSQL. Обязательно упомяните xmin/xmax и то, что UPDATE создаёт новую версию строки (а не изменяет существующую). Связка MVCC -> dead tuples -> VACUUM показывает системное понимание.