У меня есть локальная установка базы данных 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 ГБ. Любой совет высоко ценится.
postgresql
disk-space
Сообщество
источник
источник
pg_catalog
и таблицы вinformation_schema
. Так что попробуйте посмотреть, есть ли это, сняв эти ограничения вWHERE
предложении. Пожалуйста, покажите вашу точную версию PostgreSQL (SELECT version()
) и что именно вы делаете для «очистки всей базы данных», то есть точную команду. Если возможно, запуститеVACUUM FULL VERBOSE;
(без аргументов) и вставьте куда-нибудь вывод, затем ссылку на него здесь.Ответы:
Хотя вы не заявили об этом, я предполагаю из ваших ссылок на документы, за которыми вы следили, что вы сделали VACUUM FULL для базы данных и / или для затронутых таблиц. Вы также не указали, какую версию postgresql вы используете - я предполагаю, что она> 9.0 (VACUUM FULL до этого вел себя иначе).
VACUUM FULL перепишет затронутые таблицы в новые файлы, затем удалит старые файлы. Однако, если какой-либо процесс все еще имеет открытый старый файл, операционная система фактически не удалит файл - пока последний процесс не закроет его.
Если это целесообразно, перезапуск базы данных обеспечит закрытие всех открытых файлов.
Если это нецелесообразно, то вы можете проверить, является ли это вашей проблемой, и выяснить, в каком процессе открыты файлы.
Если вы используете Linux (или большинство других Unix-подобных систем), вы можете использовать команду 'lsof', чтобы получить список всех файлов, открытых во всех процессах. К файлам, которые открыты, но которые с тех пор были удалены, будет добавлено «(удалено)» к имени файла. Таким образом, вы можете получить вывод lsof для поиска удаленных файлов, например так:
Если это идентифицирует процессы, у которых все еще открыты старые файлы, вы можете использовать pg_terminate_backend, чтобы завершить этот процесс:
где xxx - PID процесса, найденный в выводе lsof.
При использовании Windows может применяться тот же принцип, поскольку postgres открывает файлы с помощью флага FILE_SHARE_DELETE, который позволяет удалять файлы, открытые в другом процессе. Команда ' handle ' является грубым эквивалентом lsof, хотя я не уверен, сможете ли вы определить, удалены ли файлы или нет, поэтому может потребоваться дополнительная работа.
Другой вопрос, почему любые такие процессы будут зависеть от старых файловых дескрипторов. Однако в теме, которую вы цитировали в своем вопросе, Том Лейн, похоже, подразумевает, что это может произойти.
источник