Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL数据库大小(表空间大小)比计算的关系总和大得多_Postgresql - Fatal编程技术网

PostgreSQL数据库大小(表空间大小)比计算的关系总和大得多

PostgreSQL数据库大小(表空间大小)比计算的关系总和大得多,postgresql,Postgresql,大家好 我看到实际的数据库大小(在硬盘上,由pg\u database\u size()call显示)和大小之间有很大的差异,大小是由pg\u total\u relation\u size()检索的总关系大小相加计算出来的 第一个是62G,最后一个是16G(右键是从最大表中删除的数据的差值) 下面是一个简化的查询,可以显示我的系统上的差异: select current_database(), pg_size_pretty( sum(total_relation_raw_size

大家好

我看到实际的数据库大小(在硬盘上,由
pg\u database\u size()
call显示)和大小之间有很大的差异,大小是由
pg\u total\u relation\u size()
检索的总关系大小相加计算出来的

第一个是62G,最后一个是16G(右键是从最大表中删除的数据的差值)

下面是一个简化的查询,可以显示我的系统上的差异:

select current_database(),
       pg_size_pretty( sum(total_relation_raw_size)::bigint ) as calculated_database_size,
       pg_size_pretty( pg_database_size(current_database()) ) as database_size   
  from (select pg_total_relation_size(relid) as total_relation_raw_size
          from pg_stat_all_tables -- this includes also system tables shared between databases
         where schemaname != 'pg_toast' 
       ) as stats;
这里似乎有一些悬而未决的数据。当这种情况出现时,我们从数据库中转储并完全清空了大量未使用的数据


旁白:我想,这是某种数据库损坏。。。从这种情况中恢复的唯一方法是切换到热备用数据库

是否有未使用的LOB

如果你有这样的东西:

CREATE TABLE bigobjects (
    id BIGINT NOT NULL PRIMARY KEY,
    filename VARCHAR(255) NOT NULL,
    filecontents OID NOT NULL
);
其次是:

\lo_import '/tmp/bigfile'
11357
INSERT INTO bigobjects VALUES (1, 'bigfile', 11357);
TRUNCATE TABLE bigobjects;
数据库中仍然有LOB(id 11357)

您可以检查数据库中所有大型对象的pg_catalog.pg_largeobject系统目录表(建议从pg_catalog.pg_largeobject中选择DISTINCT loid,除非您希望将所有LOB数据视为八进制。)


如果您清除所有未使用的LOB并进行真空充满,您应该会看到存储空间大幅减少。我刚刚在我使用的一个个人开发数据库上尝试了这个方法,发现大小从200MB降到了10MB(正如pg_database_size(current_database())所报告的那样)。

您的查询是专门筛选pg_toast表,它可能很大。看看是否在
schemaname!='pg_toast'
为您提供更准确的答案

当这种情况出现时,我们从数据库中转储并完全清空了大量未使用的数据

我也有过类似的经历:3GB的数据库中有大量动态数据,在一个月左右的时间里,这些数据达到了20GB。 手动删除/清除有问题的表不会产生效果。。 然后我们做了一个决赛

VACUUM FULL ANALYZE 
总的来说。。。它掉了一半大小


这花了4小时,所以要小心。当BobG写入时,LOB是一个非常有效的问题,因为它们不会在删除应用程序表(包含OID)的行时被删除

这些不会被真空处理自动删除,只有在它们上运行了VACUUMLO

Vacuumlo将从数据库中删除所有未引用的LOB

示例调用:

vacuumlo -U postgres -W -v <database_name>
vacuumlo-U postgres-W-v
(我只添加了-v以使vacuumlo更加详细,这样您就可以看到它删除了多少LOB)


vacuumlo删除LOB后,您可以运行VACUUM FULL(或让自动真空过程运行)。

问题中的查询中仍然会计算大型对象,因为
pg_largeobject
显示在
pg_stat_all_表中。
。您可以通过执行此查询来验证Peter的说法:
选择relname,pg_SIZE\u PRETTY(PG_TOTAL_RELATION_SIZE(relid))来自PG_stat_all_表,其中schemaname!=“PG_toast”和类似“PG_%”的relname按PG_TOTAL_RELATION_SIZE(relid)DESC排序;
PG largeobject显示bigobjects表(和其他BLOB)的总BLOB大小。你能举一个大小和差异的例子吗?哪一个更大?O,对不起,我忘了提到实数:62G表示
pg_数据库_size()
;17G表示关系大小之和,实际上是
pg_总关系大小(regclass)
被记录为“具有指定OID或名称的表使用的总磁盘空间,包括所有索引和TOAST数据”,这就是为什么我在查询中不包括TOAST(但回答您的问题TOAST:TOAST是27G)谢谢。我首先尝试使用vacuumlo,但不起作用,然后我进行了真空完全分析并清除了90%的LOB