我在 Postgres 9.1 数据库中有两个表 ( table1
, )。table2
两者都有oid类型。每张表100万条记录。pg_largeobject
表大小约为 40GB 。我从每个表中删除了 90 万条记录,并执行了以下命令。
vacuum full analyze table1;
vacuum full analyze table2;
表大小仍然没有变化pg_largeobject
(启用自动真空)
我是否也需要执行上述命令到pg_largeobject
表格?它会影响什么吗?
你可以运行它,没问题:
甚至可能删除一些死行。细节:
但这可能不会解决您的实际问题。
当使用Postgres的大对象工具时,大对象(“blob”:二进制大对象)本身被分解成存储在系统表中的二进制数据块
pg_largeobject
。PK 由两列组成,(loid, pageno)
用于引用用户表中的 blob。OID可以多次引用同一个 blob 。loid
oid
删除用户表中的行不会删除 blob。一方面,同一个 blob 可能被多次引用。您有责任自己跟踪并实际删除“未链接”的 blob。一种方法是使用
lo_unlink()
:由于您已经使用引用删除了行,因此
oid
您需要更有创意来识别未链接的 blob。假设您没有从任何其他地方引用 blob,您可以使用此查询来修复:您需要成为超级用户才能直接访问
pg_largeobject
。table1
假设和中的列名table2
是oid
。基于pg_largeobject_metadata
Postgres 9.3 或更高版本的更简单查询(如@Daniel 评论):pg_largeobject_metadata
是公开可读的。但是我在 pg 9.3 之前的版本(包括 pg 9.1)中没有看到系统表中 blob 的 OID - 至少在手册中没有,我现在没有旧版本要测试。所以你可能必须使用我的第一个查询。前后对比:
您
VACUUM FULL
现在可以运行,然后再次测试:您将对Postgres 9.1 可用的附加模块感兴趣。
lo
该手册对您的问题有准确的描述:大胆强调我的。该模块也提供了一个解决方案:
对于每个 blob在整个数据库中仅引用一次的用例。
显然也(就像@Daniel提到的那样)
vacuumlo
: