Чтобы вернуть место в ОС, используйте VACUUM FULL. Будучи на это, я полагаю, вы бежите VACUUM FULL ANALYZE. Я цитирую руководство :
FULL
Выбирает «полный» вакуум, который может освободить больше места , но занимает гораздо больше времени и исключительно блокирует стол. Этот метод также требует дополнительного дискового пространства, поскольку он записывает новую копию таблицы и не освобождает старую копию до завершения операции. Обычно это следует использовать только в том случае, если из таблицы необходимо извлечь значительный объем пространства.
Жирный акцент мой.
CLUSTER это тоже достигается как побочный эффект.
Обычный VACUUMобычно не достигает вашей цели ( «одна или несколько страниц в конце таблицы полностью свободны» ). Он не переупорядочивает строки, а только удаляет пустые страницы из физического конца файла, когда появляется такая возможность - как указывается в вашей цитате из руководства.
Вы можете получить пустые страницы в конце физического файла, когда вы делаете INSERTсерию строк и DELETEих до добавления других кортежей. Или это может произойти по совпадению, если будет удалено достаточное количество строк.
Есть также специальные настройки, которые могут помешать VACUUM FULLосвобождению пространства. Видеть:
Подготовьте пустые страницы в конце таблицы для тестирования
Системный столбец ctidпредставляет физическое положение строки. Вы должны понимать эту колонку:
Мы можем работать с этим и подготовить таблицу, удалив все строки с последней страницы:
DELETE FROM tbl t
USING (
SELECT (split_part(ctid::text, ',', 1) || ',0)')::tid AS min_tid
, (split_part(ctid::text, ',', 1) || ',65535)')::tid AS max_tid
FROM tbl
ORDER BY ctid DESC
LIMIT 1
) d
WHERE t.ctid BETWEEN d.min_tid AND d.max_tid;
Теперь последняя страница пуста. Это игнорирует одновременные записи. Либо вы единственный, кто пишет в эту таблицу, либо вам нужно взять блокировку записи, чтобы избежать помех.
Запрос оптимизирован для быстрой идентификации подходящих строк. Второе число a tid- это индекс кортежа, хранящийся как unsigned int2, и 65535это максимум для этого типа ( 2^16 - 1), так что это безопасная верхняя граница.
SQL Fiddle (повторное использование простой таблицы из другого случая.)
Инструменты для измерения размера строки / таблицы:
Диск полон
Вам нужно место для маневра на диске для любой из этих операций. Существует также инструмент сообщества в pg_repackкачестве замены для VACUUM FULL/ CLUSTER. Это исключает эксклюзивные блокировки, но требует свободного места для работы. Руководство:
Требует свободного места на диске вдвое больше, чем целевые таблицы и индексы.
В крайнем случае, вы можете запустить цикл дампа / восстановления. Это также удаляет все навороты из таблиц и индексов. Тесно связанный вопрос:
Ответ там довольно радикальный. Если ваша ситуация допускает это (без внешних ключей или других ссылок, препятствующих удалению строк) и одновременного доступа к таблице), вы можете просто:
Создайте дамп таблицы с диском, соединяющимся с удаленным компьютером с большим количеством дискового пространства ( -aдля --data-only):
Из удаленной оболочки выгрузите данные таблицы:
pg_dump -h <host_name> -p <port> -t mytbl -a mydb > db_mytbl.sql
В сеансе pg TRUNCATEтаблица:
-- drop all indexes and constraints here for best performance
TRUNCATE mytbl;
Из удаленной оболочки восстановите ту же таблицу:
psql -h <host_name> -p <port> mydb -f db_mytbl.sql
-- recreate all indexes and constraints here
Это теперь свободно от любых мертвых рядов или раздувания.
Но, может быть, вы можете иметь это проще?
Можете ли вы освободить достаточно места на диске, удалив (переместив) несвязанные файлы?
Можете ли вы VACUUM FULLсначала уменьшать размер таблиц, освобождая, таким образом, достаточно места на диске?
Можно ли запустить REINDEX TABLEили REINDEX INDEXосвободить место на диске от раздутых индексов?
Что бы ты ни делал, не будь опрометчивым . Если сомневаетесь, сначала сделайте резервную копию всего в безопасном месте.