Как происходит обновление строк (rows) в PostgreSQL?

Ответ

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

Когда вы выполняете команду UPDATE, происходит следующее:

  1. Создание новой версии: PostgreSQL создает новую версию строки (новую запись или tuple) с обновленными данными.
  2. Пометка старой версии: Старая версия строки не удаляется физически, а помечается как "неактуальная" для текущей и последующих транзакций. Это делается путем установки системного поля xmax в ID транзакции, которая произвела обновление.
  3. Очистка: Со временем фоновый процесс VACUUM находит и окончательно удаляет старые, уже невидимые ни для одной транзакции версии строк, освобождая место.

Пример:

После этой команды в таблице физически будут существовать две версии строки для id = 1, но только новая будет видна для последующих запросов.

Ключевые преимущества этого подхода:

  • Отсутствие блокировок при чтении: Читающие транзакции не блокируют пишущие, и наоборот. Каждый видит свой "снимок" данных.
  • Согласованность данных: Каждая транзакция работает с консистентным срезом данных, который не меняется во время ее выполнения.
  • Возможность отката (Rollback): Для отката транзакции достаточно просто пометить созданные ею версии строк как недействительные.

Недостаток:

  • Разрастание таблицы (bloat): Без регулярной работы VACUUM таблица будет занимать больше места на диске из-за "мертвых" версий строк.