MVCC (Multi-Version Concurrency Control) - спосіб дати паралельним транзакціям узгоджений знімок даних без блокувань на читання. Читачі не блокують письменників, письменники - читачів.
Як це влаштовано в PostgreSQL: UPDATE не змінює рядок на місці, а створює нову версію рядка, позначаючи стару як застарілу (з якої транзакції вона вже невидима). DELETE лише позначає рядок. Кожна транзакція бачить ті версії, що були актуальні на момент її знімка.
Звідси потреба у VACUUM: старі версії («мертві кортежі») лишаються в таблиці, доки жодна транзакція вже не може їх бачити. VACUUM:
- звільняє місце мертвих кортежів для повторного використання;
- оновлює visibility map (потрібна для index-only scan);
- «заморожує» старі ідентифікатори транзакцій, щоб уникнути переповнення лічильника транзакцій (transaction ID wraparound) - аварійної ситуації, за якої база перестає приймати запис.
Зазвичай усе це робить фоновий autovacuum.
Типові проблеми на проді:
- Роздування (bloat) таблиць з частими
UPDATE: autovacuum не встигає, таблиця й індекси ростуть, запити сповільнюються. Лікують тонким налаштуванням autovacuum для конкретних таблиць. - Довга транзакція (чи забута відкрита сесія
idle in transaction) не дає вакууму прибирати навіть старі версії по всій базі. VACUUM FULLповертає місце ОС, але переписує таблицю під ексклюзивним блокуванням - на проді його уникають.
InnoDB теж використовує MVCC, але зберігає старі версії в undo log, тож окремого вакууму не потребує (його роль виконує фоновий purge).