VACUUM в PostgreSQL: почему DELETE не удаляет, а база пухнет
В PostgreSQL `DELETE` не стирает данные. Он просто делает строку «невидимой». Физически она остается на диске. Спасибо MVCC — так читатели не блокируют писателей.
Как это работает?
Представьте кусок швейцарского сыра. `VACUUM` выедает дырки (мертвые строки). Размер куска не меняется, но новые данные теперь можно лить в эти пустоты. Без блокировок таблицы.
Зачем это нужно, кроме экономии места?
1. Статистика. Если ее не обновлять, планировщик запросов начнет тупить и жечь CPU.
2. XID Wraparound. Если не замораживать старые транзакции, счетчик ID переполнится, и база уйдет в `read-only`. Чинить такое больно.
Виды уборки:
• `VACUUM` — просто помечает место как свободное. Файл на диске меньше не станет.
• `VACUUM FULL` — пересоздает таблицу с нуля, возвращает место ОС. Блокирует таблицу наглухо. На проде лучше заменить на `pg_repack`.
• `AUTOVACUUM` — фоновый уборщик.
Как не положить прод?
Дефолтный авто-vacuum ленив. Для тяжелых таблиц режьте настройки:
Чек-лист:
Зайдите в `pg_stat_user_tables`. Если в `n_dead_tup` миллионы строк, а `last_autovacuum` был давно — база задыхается.
После большой заливки данных не забывайте делать:
`VACUUM (VERBOSE, ANALYZE) your_table;`
А у вас `AUTOVACUUM` вывозит или ручками чистите?
В PostgreSQL `DELETE` не стирает данные. Он просто делает строку «невидимой». Физически она остается на диске. Спасибо MVCC — так читатели не блокируют писателей.
Как это работает?
Представьте кусок швейцарского сыра. `VACUUM` выедает дырки (мертвые строки). Размер куска не меняется, но новые данные теперь можно лить в эти пустоты. Без блокировок таблицы.
Зачем это нужно, кроме экономии места?
1. Статистика. Если ее не обновлять, планировщик запросов начнет тупить и жечь CPU.
2. XID Wraparound. Если не замораживать старые транзакции, счетчик ID переполнится, и база уйдет в `read-only`. Чинить такое больно.
Виды уборки:
• `VACUUM` — просто помечает место как свободное. Файл на диске меньше не станет.
• `VACUUM FULL` — пересоздает таблицу с нуля, возвращает место ОС. Блокирует таблицу наглухо. На проде лучше заменить на `pg_repack`.
• `AUTOVACUUM` — фоновый уборщик.
Как не положить прод?
Дефолтный авто-vacuum ленив. Для тяжелых таблиц режьте настройки:
ALTER TABLE heavy_table
SET (autovacuum_vacuum_scale_factor = 0.01, -- вместо дефолтных 0.2
autovacuum_vacuum_threshold = 500,
autovacuum_work_mem = '1GB');
Чек-лист:
Зайдите в `pg_stat_user_tables`. Если в `n_dead_tup` миллионы строк, а `last_autovacuum` был давно — база задыхается.
После большой заливки данных не забывайте делать:
`VACUUM (VERBOSE, ANALYZE) your_table;`
А у вас `AUTOVACUUM` вывозит или ручками чистите?