Что такое MVCC в PostgreSQL и как работает версионирование данных?

Ответ

В PostgreSQL параллельный доступ к данным реализован через механизм MVCC (Multi-Version Concurrency Control) — управление конкурентным доступом через многоверсионность. Это позволяет нескольким транзакциям читать и изменять данные одновременно, минимизируя блокировки.

Ключевые принципы:

  1. Снимки данных: Каждая транзакция работает со своим «снимком» (snapshot) данных, который был актуален на момент её начала. Она не видит изменений, сделанных другими транзакциями, которые начались позже.
  2. Версии строк: Вместо того чтобы изменять данные «на месте», PostgreSQL создает новую версию строки при каждом UPDATE. Старая версия не удаляется сразу, а помечается как неактуальная.

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

Каждая строка в таблице имеет скрытые системные поля:

  • xmin: ID транзакции, которая создала эту версию строки.
  • xmax: ID транзакции, которая удалила (или обновила) эту версию строки. Изначально равен 0.

Пример жизненного цикла строки:

-- 1. Транзакция с ID=100 вставляет новую строку.
-- Для этой строки xmin=100, xmax=0.
BEGIN; -- txid 100
INSERT INTO users (name) VALUES ('Alice');
COMMIT;

-- 2. Транзакция с ID=200 обновляет эту строку.
-- PostgreSQL выполняет два действия:
--   a) Помечает старую версию строки: xmax=200.
--   b) Создает новую версию строки с данными 'Bob' и xmin=200.
BEGIN; -- txid 200
UPDATE users SET name = 'Bob' WHERE name = 'Alice';
COMMIT;

Очистка старых версий:

«Мертвые» версии строк, которые больше не видны ни одной активной транзакции, удаляются фоновым процессом VACUUM. Это необходимо для освобождения места и предотвращения разрастания таблиц.