PostgreSQL 数据膨胀解决方法不完全指南
PostgreSQL 中的数据膨胀(bloat)是指数据表或者索引中无用数据过多占用空间的情况。PostgreSQL 通过元组中的 xmin/xmax 以及可见性判断逻辑来实现 MVCC,当更新或删除一条元组的时候,会更新它的 xmax 来标记删除而非真正进行物理删除,因此如果大量死元组未及时清理,会出现数据膨胀,占用额外存储空间且影响查询性能。本文我们讨论数据膨胀的主要原因以及如何检查并解决的方法。 膨胀原因 PostgreSQL 中的 autovacuum launcher 在满足条件时会启动 autovacuum worker 去清理垃圾数据,但当出现以下情况时,依旧会出现膨胀的现象: 设置了 autovauum_enabled = false,防止 autovacuum 进程清理该表(但如果表 age 过大,autovacuum 依然会处理该表以防止 transaction ID wraparound 问题出现) 长事务,如果一个事务长时间未结束,会阻止 vacuum 进程清理该事务 id 之后修改或删除的元组 更新/删除频繁的业务负载 autovacuum 参数配置不合理 检查是否存在膨胀 检查数据膨胀的方法有很多,常用于监控或异常时手动检查,下面列举几种检查的方法。 pg_stat_user_tables pg_stat_user_tables 提供了用户表各种运行状态信息,其中 n_live_tup 和 n_dead_tup 表示一张表中活元组和死元组近似数值,以下查询可以检测数据膨胀情况: SELECT schemaname, relname, n_live_tup, n_dead_tup, last_vacuum, last_autovacuum, vacuum_count, autovacuum_count FROM pg_stat_user_tables ORDER BY 2, 3 DESC; 上述查询还会输出一些跟 vacuum 相关的字段以检测 vacuum 在该表上运行的情况。pg_stat_user_tables 还可以查看 seq_scan 和 idx_scan 的统计信息以帮助用户更好地优化索引的创建。...