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