内容提要
Postgres表的数据默认采用“堆”方法存储,数据分为1GB的文件和8KB的页面。更新时生成新版本,旧版本保留以便回滚。清理旧版本的过程称为“真空”,可自动运行。使用“VACUUM FULL”可释放文件系统空间,但需独占锁。调整自动真空参数可提高效率,避免数据库膨胀。
延伸解读
真空如何提升索引查询效率
真空不仅释放页面空间,还会更新可见性映射,标记页面中所有剩余行对所有事务可见。这样索引扫描可以跳过可见性检查,直接返回结果,从而显著加快使用索引的查询。对于频繁更新的表,定期真空有助于维持查询性能。
VACUUM FULL 与 pg_repack 的取舍
VACUUM FULL 通过重建表来紧凑存储活行,从而释放文件系统空间,但需要独占锁,期间无法修改表,建议在访问量低时执行。如果无法承受锁,可考虑 pg_repack 扩展,它能在不获取全锁的情况下达到类似效果,但需额外安装和配置。
自动真空未启动的常见原因
自动真空的触发取决于多个参数,如 autovacuum_vacuum_threshold 和 autovacuum_vacuum_scale_factor。默认 scale factor 为 20%,对于大表可能过高,导致真空启动不及时。可以针对大表降低该值,例如设为 0.05,使自动真空更频繁地运行,每次处理更少数据。
长时间事务与锁导致膨胀
自动真空失败最常见的原因是存在长时间运行的事务,它们可能仍需要旧行版本,导致这些版本无法被标记为死行,数据库因此膨胀。此外,某些操作如 ALTER TABLE 会获取 SHARE UPDATE EXCLUSIVE 锁,阻止真空处理表。定期检查并关闭空闲事务,或手动执行 VACUUM,有助于缓解膨胀。
Q&A
Postgres中的数据是如何存储的?
Postgres中的数据默认采用“堆”方法存储,数据分为1GB的文件和8KB的页面。
什么是真空过程,它的作用是什么?
真空过程是清理旧版本数据的异步过程,释放页面上的空间并更新表的自由空间映射。
如何使用VACUUM FULL释放文件系统空间?
使用VACUUM FULL可以释放文件系统空间,但需要独占锁,建议在数据库访问量少时执行。
自动真空参数如何调整以提高效率?
可以通过增加自动真空工作内存和工人数量,或调整阈值和比例因子来优化自动真空过程。
长时间运行的事务会对自动真空产生什么影响?
长时间运行的事务可能导致自动真空失败,从而引起数据库膨胀,因为旧版本的数据无法被标记为死数据。
如何检查数据库的膨胀情况?
可以通过Supabase CLI运行相关命令,查看死行和活行的数量,判断数据库是否膨胀。