pg数据库运行一段时间之后,突然变慢了,是时候进行一波vacuum了

死亡数据 Dead tuples
VACUUM
是PostgreSQL
内置的垃圾回收清理工具,用来清理无用的元组数据占用的空间。对于PostgreSQL
而言,被删除或者被Update
之后过时的数据并不会被物理删除,只有运行了VACUUM
命令,这些空间才会被释放。因此,需要周期性地运行VACUUM
,尤其是频繁更新的表。
那么问题就来了,如果是DELETE
操作,PostgreSQL
目前的存储引擎会在原HEAP PAGE中保留老的记录版本,如果是UPDATE
操作,则会写入一条新版本。而表上的索引也会产生新版本,索引也会产生新的记录。这些无效的数据被称之为dead tuples
,使用VACUUM
命令可以清理这些无效数据,显著提升性能。
VACUUM和autovacuum
对于VACUUM
,最直接的方式,就是执行手动VACUUM
命令,这个命令会清理dead tuples
。VACUUM会并发扫描全表,然后清理无效数据。但是要慎用VACUUM FULL
,因为加了FULL
会锁表,并且会删除所有数据并新建,会导致性能占用比较高。
autovacuum
则是一个内置的daemon
程序,会在一定情况下自动触发vacuum
进程,从而无需手动进行配置
autovacuum 触发参数
两个参数可以配置在启动参数中,也可以通过pg_settings(以下是阿里云RDS
默认参数)查到:
autovacuum_vacuum_threshold = 50 autovacuum_vacuum_scale_factor = 0.02
当pg_stat_all_tables.n_dead_tup
超过了
threshold + pg_class.reltuples
* scale_factor
那么自动VACUUM
就会被触发了。
实战总结
大部分情况下默认参数是足够的 默认参数不够用的情况下,可以调整 autovacuum_vacuum_scale_factor
,但是需要重启可以通过查询计划判断是否有查询过多的记录,配合 n_dead_tup
和pg_class.reltuples
来排查问题可以配置定时任务执行 VACUUM
,使用VACUUM ANALYZE
不仅可以清除无效数据,pg_class.reltuples
也会刷新。
文章转载自云原生外卖小哥,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。





