Как освободить место на диске в PostgreSQL?

25

У меня есть локальная установка базы данных 9.1 с несколькими таблицами, которые имели cca. 300 миллионов записей и база данных выросли до 20 ГБ. После этого я дал delete fromкоманду удалить все записи из него (я должен был использовать truncate, но я этого не знал). Поэтому я полностью опустошил свою базу данных, чтобы освободить место на диске, но это не помогло. Моя проблема выглядит идентично этой , но не предоставлено никакого решения. Я уже проверил этот поток и документацию по «восстановлению дискового пространства» , но все еще не могу найти решение. Я использую этот код, чтобы получить размер всех таблиц

 SELECT nspname || '.' || relname AS "relation",
 pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
 FROM pg_class C
 LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
 WHERE nspname NOT IN ('pg_catalog', 'information_schema')
 AND C.relkind <> 'i'
 AND nspname !~ '^pg_toast'
 ORDER BY pg_total_relation_size(C.oid) DESC
 LIMIT 15;

Всего до 1 ГБ, однако

SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) AS size FROM pg_database 

до сих пор показывает около 20 ГБ. Любой совет высоко ценится.

Сообщество
источник
Ну, ваш размерный запрос исключает: индексы, таблицы в pg_catalogи таблицы в information_schema. Так что попробуйте посмотреть, есть ли это, сняв эти ограничения в WHEREпредложении. Пожалуйста, покажите вашу точную версию PostgreSQL ( SELECT version()) и что именно вы делаете для «очистки всей базы данных», то есть точную команду. Если возможно, запустите VACUUM FULL VERBOSE;(без аргументов) и вставьте куда-нибудь вывод, затем ссылку на него здесь.
Крейг Рингер,
Попробуйте сбросить базу данных. Вы также можете попробовать сбросить базу данных, а затем ее восстановление приведет к удалению мусора.
JB.
1
@jb Это бы сработало, но не обязательно. Лучше узнать, в чем проблема.
Крейг Рингер,

Ответы:

22

Хотя вы не заявили об этом, я предполагаю из ваших ссылок на документы, за которыми вы следили, что вы сделали VACUUM FULL для базы данных и / или для затронутых таблиц. Вы также не указали, какую версию postgresql вы используете - я предполагаю, что она> 9.0 (VACUUM FULL до этого вел себя иначе).

VACUUM FULL перепишет затронутые таблицы в новые файлы, затем удалит старые файлы. Однако, если какой-либо процесс все еще имеет открытый старый файл, операционная система фактически не удалит файл - пока последний процесс не закроет его.

Если это целесообразно, перезапуск базы данных обеспечит закрытие всех открытых файлов.

Если это нецелесообразно, то вы можете проверить, является ли это вашей проблемой, и выяснить, в каком процессе открыты файлы.

Если вы используете Linux (или большинство других Unix-подобных систем), вы можете использовать команду 'lsof', чтобы получить список всех файлов, открытых во всех процессах. К файлам, которые открыты, но которые с тех пор были удалены, будет добавлено «(удалено)» к имени файла. Таким образом, вы можете получить вывод lsof для поиска удаленных файлов, например так:

sudo lsof -u postgres | grep 'deleted'

Если это идентифицирует процессы, у которых все еще открыты старые файлы, вы можете использовать pg_terminate_backend, чтобы завершить этот процесс:

SELECT pg_terminate_backend(xxx);

где xxx - PID процесса, найденный в выводе lsof.

При использовании Windows может применяться тот же принцип, поскольку postgres открывает файлы с помощью флага FILE_SHARE_DELETE, который позволяет удалять файлы, открытые в другом процессе. Команда ' handle ' является грубым эквивалентом lsof, хотя я не уверен, сможете ли вы определить, удалены ли файлы или нет, поэтому может потребоваться дополнительная работа.

Другой вопрос, почему любые такие процессы будут зависеть от старых файловых дескрипторов. Однако в теме, которую вы цитировали в своем вопросе, Том Лейн, похоже, подразумевает, что это может произойти.

harmic
источник
Мне нужно было срочно вернуть дисковое пространство, поэтому я удалил базу данных и восстановил ее из резервной копии. Однако, «как» решить эту проблему, все еще очень ценно для будущих случаев. Моя база данных 9.1, win 8 64 bit, применяется ли именование файлов (случай открытых файлов) так же, как в linux?
@arcull Хорошо, я не понял, что вы используете Windows. Я добавил некоторую информацию в ответ о том, как это относится к Windows. Если вы считаете, что это может быть полезным ответом, рассмотрите возможность голосования, поскольку другим будет легче его найти.
вредно