Получить доступ

Что такое MVCC и как он позволяет читать без блокировок?

MiddleХранение данных
Ещё спрашивают так:
  • Как PostgreSQL хранит версии строк?
  • Зачем нужен VACUUM?
  • Почему читатели не блокируют писателей?
Коротко

Многоверсионность: изменение строки создаёт новую версию, а старая остаётся. Каждая транзакция читает снимок — версии, подтверждённые до её начала (или до начала запроса).

  • Читатели не блокируют писателей и наоборот; блокируются только два писателя одной строки
  • В PostgreSQL версия помечена xmin/xmax — номерами создавшей и удалившей транзакций
  • Старые версии убирает VACUUM; долгие транзакции мешают уборке — таблица «раздувается»

А ещё В Oracle и InnoDB старые версии лежат в undo-журнале, а не в таблице

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Попробуйте сами

Уровни изоляции: версии строк, снимки и аномалии

Подробно

Без многоверсионности согласованное чтение требует блокировок: пока транзакция читает, писатель ждёт, и наоборот. MVCC снимает это противоречие — у каждой транзакции своя точка зрения на данные.

Как это устроено в PostgreSQL:

  • каждая версия строки (tuple) хранит xmin — транзакцию, которая её создала, и xmax — транзакцию, которая её удалила или заменила;
  • UPDATE не перезаписывает строку: он ставит xmax старой версии и вставляет новую с xmin = текущая транзакция;
  • снимок — список транзакций, которые на момент его взятия уже завершились; версия видна, если её xmin подтверждён в снимке, а xmax — нет;
  • в Read Committed снимок берётся на каждый запрос, в Repeatable Read — один на всю транзакцию.

Что даёт: длинный отчёт видит согласованное состояние базы на момент начала и никого не блокирует. Писатели блокируют друг друга только на одной и той же строке — второй ждёт коммита или отката первого.

Цена — старые версии. Они нужны, пока жива транзакция, которая может их увидеть. Убирает их VACUUM (autovacuum в фоне): освобождает место под новые версии. Проблемы:

  • раздувание (bloat) — частые UPDATE при отстающем автовакууме;
  • долгая транзакция или забытая idle in transaction держит горизонт: ни одна версия новее её начала не может быть убрана во всей базе. Таблицы пухнут, запросы замедляются. Ищут через pg_stat_activity, ставят idle_in_transaction_session_timeout;
  • переполнение счётчика транзакций — 32-битные номера, нужна заморозка (freeze) старых строк, иначе база остановится для защиты.

Другие реализации. InnoDB и Oracle меняют строку на месте, а прошлую версию кладут в undo-журнал; читатель со старым снимком восстанавливает нужную версию из undo. Уборка — purge-поток. Плюс: таблица не пухнет; минус: долгий снимок раздувает undo и замедляет чтения.

MVCC и аномалии. Снимок защищает от грязного и неповторяемого чтения, но не от всех аномалий: на Repeatable Read (Snapshot Isolation) возможна асимметрия записи (write skew). Полную сериализуемость PostgreSQL даёт уровнем Serializable (SSI) — с откатом транзакций при конфликте.

Пример

-- сеанс 1
BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT balance FROM accounts WHERE id = 1;    -- 100
-- сеанс 2: UPDATE accounts SET balance = 50 WHERE id = 1; COMMIT;
SELECT balance FROM accounts WHERE id = 1;    -- всё ещё 100 — свой снимок
COMMIT;

SELECT xmin, xmax, balance FROM accounts WHERE id = 1;   -- видно номер транзакции-создателя

Что хотят услышать

  • Версии строк вместо перезаписи, снимок у транзакции.
  • Почему читатели и писатели не блокируют друг друга.
  • Устройство в PostgreSQL: xmin/xmax, VACUUM.
  • Проблема долгих транзакций и раздувания.
  • Отличие от undo-подхода и связь с уровнями изоляции — плюс.

Частые ошибки

  • Считать, что MVCC устраняет все конфликты записи.
  • Не связывать «таблица распухла» с открытой долгой транзакцией.

Что спросят дальше

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем