如何在PostgreSQL上回收磁盘空间?


25

我在本地安装了9.1数据库,只有几个表具有cca。300 mio记录,数据库增长到约20 GB。之后,我发出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;

总计不足1GB

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

仍显示约20 GB。任何建议,不胜感激。


好吧,您的大小查询不包括:索引,中的表pg_catalog和中的表information_schema。因此,请通过删除该WHERE子句中的限制来尝试查看是否有这些限制。请显示您的确切PostgreSQL版本(SELECT version()),以及您要“清空整个数据库”的确切操作,即确切的命令。如果可能,请运行VACUUM FULL VERBOSE;(无参数)并将输出粘贴到某个位置,然后在此处链接到它。
Craig Ringer 2014年

尝试删除数据库。您也可以尝试转储数据库,然后还原它会丢弃垃圾。
jb。

1
@jb可以,但是没有必要。更好地了解问题所在。
Craig Ringer 2014年

Answers:


22

尽管您没有声明,但是从您对文档的引用中,我认为您已经对数据库和/或受影响的表进行了VACUUM FULL。您也没有指定要使用的postgresql版本-我将假定它是9.0以上(在此之前VACUUM FULL的行为有所不同)。

VACUUM FULL将受影响的表重写为新文件,然后删除旧文件。但是,如果仍有任何进程打开了旧文件,则操作系统将不会实际删除该文件-直到最后一个进程将其关闭为止。

如果可行,重新启动数据库将确保关闭所有打开的文件。

如果这不切实际,那么您也许可以验证这是否是您的问题,并找出哪个进程打开了文件。

如果使用Linux(或大多数其他类似Unix的系统),则可以使用“ lsof”命令获取在所有进程中打开的所有文件的列表。打开但已删除的文件将在文件名后附加“(已删除)”。因此,您可以grep 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大致等效,尽管我不确定是否可以确定文件是否已删除,所以可能需要一些额外的工作。

关于为什么这样的进程将挂在旧文件句柄上,这是另一个问题。然而,在线程,你在你的问题引用,汤姆里似乎在暗示,它可能发生。


我必须紧急收回磁盘空间,因此删除了数据库并从备份中还原了它。但是,“如何”解决此问题对于将来的案例仍然非常有价值。我的数据库是9.1,Win 8 64位,文件命名(打开文件的情况)是否适用于Linux?

@arcull OK,我没有意识到您正在使用Windows。我在答案中添加了一些有关如何将其应用于Windows的信息。如果您认为这可能是一个有用的答案,请考虑投票,因为它可以使其他人更容易找到它。
2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.