You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何PostgreSQL的VACUUM仅扫描4GB数据,而数据库为58GB?

问题解答

pg_stat_progress_vacuum中的heap_blks_total仅统计用户表的堆数据块,而数据库的总大小包含了大量VACUUM不会扫描的内容,这就是两者差异的核心原因,具体拆解:

  • 索引是独立存储的:你导入数据时创建的索引会占用大量空间,这部分会被算进数据库总大小,但普通VACUUM不会将索引块计入heap_blks_total(仅在清理死元组时少量处理索引,但不会统计到这个字段里)。
  • 未被使用的空闲块:如果导入时用了批量插入、预分配存储空间(比如fillfactor配置或表空间预分配),会产生很多空块,这些块属于数据库总大小,但VACUUM只会扫描包含有效数据或死元组的堆块,空块不被统计。
  • TOAST表的额外存储:大字段(如text、bytea)超出页大小的部分会存在TOAST表中,TOAST表的块不会计入主表的heap_blks_total,但会算进数据库总大小。
  • 数据库的其他组成部分:总大小还包含pg_wal目录的WAL日志、临时文件、系统目录表、配置文件等,这些都不属于用户表堆的范畴,VACUUM完全不会扫描它们。
  • 刚导入的表无大量死元组:你是空库导入数据,且导入时关闭了autovacuum,导入后几乎没有死元组,VACUUM仅需要扫描表堆中实际存了数据的部分,不需要处理那些预分配但空的块。

你计算出的约4GB,正是VACUUM实际需要处理的用户表堆数据量,而58GB是数据库所有文件的总和,两者统计范围完全不同。

内容的提问来源于stack exchange,提问作者Fabrice Chapuis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 16:35:21