PostgreSQL pg_database_size 不同于 pg_total_relation_size 的总和

PostgreSQL pg_database_size different from sum of pg_total_relation_size

目前,我的开发数据库占用的磁盘 space 比它可能应该占用的要多得多。该项目使用 Django、Docker-Machine 和 PostgreSQL。奇怪的是,当我使用 pg_database_size() 时,它说使用了大约 9MB 的磁盘 space (上传的文件只有 20KB)。但是,当我总结所有 table 的大小时(即总结对查询 SELECT relname FROM pg_class WHERE relkind='r' AND relname !~ '^(pg_|sql_)'; 返回的每个 table 名称执行 pg_total_relation_size() 的结果),报告的总大小仅为 1.8MB。我正在使用 psycopg2 来查询我的数据库。

为什么尺寸会有如此大的差异?我看到了类似的问题,答案似乎是清除所有未正确删除的 LOB。我做了以下事情:

docker exec -it <name_of_database_container> vacuumlo -U postgres -W -v postgres

它报告说它成功删除了 0 个 LOB,所以看起来 LOB 从来都不是我的问题。还会发生什么?我是否没有使用 SELECT relname.... 查询正确获取所有 table 名称?

您的 pg_total_relation_size 查询排除了以 pg_ 开头的系统表。这些表 do 仍然占用 space.

我手中的最小可能(未损坏)数据库约为 7.2MB。所以你给出的数字算出来了。

pg_total_relation_size 的文档说它包括索引的大小,但我的数据库并非如此。这可能是因为我使用显式名称而不是匿名索引创建了索引。

这里有一些查询可以帮助追踪 space 的去向:

-- total database size on disk
select * from pg_size_pretty(pg_database_size('etlq'));

-- total sizes by schema
select nspname, pg_size_pretty(sum(pg_total_relation_size(C.oid)))
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
GROUP BY nspname;

-- total size by relation
select nspname, relname, pg_size_pretty(pg_total_relation_size(C.oid)), pg_total_relation_size(c.oid)
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE true
and pg_total_relation_size(C.oid) > 10 * 1024 * 1024 -- greater than 10MB
ORDER BY pg_total_relation_size(C.oid) DESC, nspname;