Ответ
Обновление строк в PostgreSQL происходит не путем изменения существующих данных на месте, а через механизм MVCC (Multi-Version Concurrency Control) — управление параллельным доступом посредством многоверсионности.
Когда вы выполняете команду UPDATE
, происходит следующее:
- Создание новой версии: PostgreSQL создает новую версию строки (новую запись или
tuple
) с обновленными данными. - Пометка старой версии: Старая версия строки не удаляется физически, а помечается как "неактуальная" для текущей и последующих транзакций. Это делается путем установки системного поля
xmax
в ID транзакции, которая произвела обновление. - Очистка: Со временем фоновый процесс
VACUUM
находит и окончательно удаляет старые, уже невидимые ни для одной транзакции версии строк, освобождая место.
Пример:
После этой команды в таблице физически будут существовать две версии строки для id = 1
, но только новая будет видна для последующих запросов.
Ключевые преимущества этого подхода:
- Отсутствие блокировок при чтении: Читающие транзакции не блокируют пишущие, и наоборот. Каждый видит свой "снимок" данных.
- Согласованность данных: Каждая транзакция работает с консистентным срезом данных, который не меняется во время ее выполнения.
- Возможность отката (Rollback): Для отката транзакции достаточно просто пометить созданные ею версии строк как недействительные.
Недостаток:
- Разрастание таблицы (bloat): Без регулярной работы
VACUUM
таблица будет занимать больше места на диске из-за "мертвых" версий строк.