Vacuum

Vacuum 是PG 为了实现MVCC(多版本并发控制)而采用的一种技术。
通过保留变更前的记录来实现MVCC的。当数据记录被DML修改,旧版本记录仍保留不变,仅仅需要修改相关记录的xmin、xmax属性,并新增写入变更后的版本记录数据。

由于历史版本数据仍然保留在原表空间中,默认情况下autovacuum会按照一定的参数设置策略检测并进行一定的清理,但频繁的数据变极大可能导致旧版本数据空间来不及进行空间回收,从而导致表空间膨胀。

PG直接保留旧版本数据的方式,每次DML操作都需要额外的日志写入,存在一定的IO消耗(目前SSD盘存储下,感觉影响不会很大);

PG这种直接保留旧版本数据的方式,无需额外的日志写入的消耗,但是一定程度上会导致旧版本数据没有及时清理,导致表空间膨胀,影响该表数据的查询效率(扫描了不必要的数据页)。


AutoVacuum 参数
autovacuum为PG数据库中可以实现自动vacuum的一个守护进程(postgres: autovacuum launcher),需要数据库将参数autovacuum参数打开。

autovacuum会自动检测发生了大量DML操作的表对象,并对其进行垃圾回收和统计信息的重新采集,相当于手动执行 vacuum analyze 。

[root@testdb ~]# ps -ef|grep postgre
postgres 112702      1  0 20:44 ?        00:00:00 /usr/pgsql-14/bin/postgres -D /data/postgresql/data14
postgres 112703 112702  0 20:44 ?        00:00:00 postgres: logger
postgres 112705 112702  0 20:44 ?        00:00:00 postgres: checkpointer
postgres 112706 112702  0 20:44 ?        00:00:00 postgres: background writer
postgres 112707 112702  0 20:44 ?        00:00:00 postgres: walwriter
postgres 112708 112702  0 20:44 ?        00:00:00 postgres: autovacuum launcher
postgres 112709 112702  0 20:44 ?        00:00:00 postgres: stats collector
postgres 112710 112702  0 20:44 ?        00:00:00 postgres: logical replication launcher
root     123251 122926  0 21:10 pts/4    00:00:00 vim postgresql.conf
root     127476 127335  0 21:20 pts/6    00:00:00 grep --color=auto postgre


在PG的配置文件中,有一部分是AutoVacuum的配置。
参数说明
autovacuum : 是否开启autovacuum守护进程,默认开启
log_autovacuum_min_duration : 指定autovacuum执行耗时超过该参数时,将对应操作记录到日志,-1表示禁用autovacuum的日志记录
autovacuum_max_workers : autovacuum可启动的最大worker数,默认为3
autovacuum_naptime : 指定两次autovacuum之间的时间延迟,默认为1min
autovacuum_vacuum_threshold 、autovacuum_vacuum_scale_factor : 指定一张表Delete、Update的tuple数超过 autovacuum_vacuum_scale_factor * table_size + autovacuum_vacuum_threshold 时,自动触发autovacuum。默认autovacuum_vacuum_threshold为50,autovacuum_vacuum_scale_factor为20
autovacuum_vacuum_insert_threshold 、 autovacuum_vacuum_insert_scale_factor : 指定一张表Insert的tuple数超过 autovacuum_vacuum_insert_scale_factor * table_size + autovacuum_vacuum_insert_threshold 时,自动触发autovacuum。默认autovacuum_vacuum_insert_threshold为50,autovacuum_vacuum_insert_scale_factor为20
autovacuum_analyze_threshold 、autovacuum_analyze_scale_factor : 指定一张表Insert、Delete、Update的tuple数超过 autovacuum_analyze_scale_factor * table_size + autovacuum_analyze_threshold 时,自动触发analyza操作。默认autovacuum_analyze_threshold为50,autovacuum_analyze_scale_factor为20
autovacuum_freeze_max_age : 为防止表中事物ID回卷,指定表的最大事物ID(pg_class.relfrozenxid),超过该参数值自动触发autovacuum,即使autovacuum参数设置为off
autovacuum_multixact_freeze_max_age : 为防止表中多个事物ID回卷,指定表的最大事物ID(pg_class.relminmxid),超过该参数值自动触发autovacuum,即使autovacuum参数设置为off
autovacuum_vacuum_cost_delay : 指定计算autovacuum的代价延迟值
autovacuum_vacuum_cost_limit : 指定autovacuum操作的代价限制值

 

AutoVacuum 工作原理
1.当参数autovacuum设置为on时,数据库会启动一个autovacuum的守护进程,当满足触发条件时启动相关的autovacuum经常进行垃圾回收操作;
2.当表update,delete的tuples数量超过 autovacuum_vacuum_scale_factor * table_size + autovacuum_vacuum_threshold 时,自动触发autovacuum操作
3.当表insert的tuples数量超过 autovacuum_vacuum_insert_scale_factor * table_size + autovacuum_vacuum_insert_threshold 时,自动触发autovacuum操作
4.当表的insert,delete,update的tuple超过 autovacuum_analyze_scale_factor * table_size + autovacuum_analyze_threshold 时,自动触发analyza操作
5.当表的最大事物ID超过autovacuum_freeze_max_age、autovacuum_multixact_freeze_max_age 时,自动触发autovacuum操作
6.默认两次autovacuum之前的时间间隔为autovacuum_naptime,且每次进行autovacuum时可启动的最大并发数为autovacuum_max_workers

 

AutoVacuum 配置
全局参数并不一定适用于所有表,特殊表可在表级别定义相关参数。例如变更频繁的表,可适当减少autovacuum_vacuum_scale_factor、autovacuum_vacuum_threshold参数值,使得其可以及时的垃圾回收,避免表膨胀影响其查询效率。

autovacuum_max_workers可根据操作系统CPU资源进行适当调整。


除了上面说的autovacuum之外,也可以手工执行。
语法如下:

VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]
where option can be one of:

    FULL [ boolean ]
    FREEZE [ boolean ]
    VERBOSE [ boolean ]
    ANALYZE [ boolean ]
    DISABLE_PAGE_SKIPPING [ boolean ]
    SKIP_LOCKED [ boolean ]
    INDEX_CLEANUP { AUTO | ON | OFF }
    PROCESS_TOAST [ boolean ]
    TRUNCATE [ boolean ]
    PARALLEL integer
and table_and_columns is:

    table_name [ ( column_name [, ...] ) ]
    
参数说明:

VACUUM FULL
执行期间需要获取对应表的独占锁,阻塞其他客户端的读写操作。该模式下会将对应表数据重新写入一个新的表空间文件,最后替换为新的表文件,这种方式下可以回收dead tuple空间并释放给操作系统。该操作执行消耗是比较大的,且耗时的。

VACUUM FREEZE
使用一种激进的方式冻结元祖,相当于把参数 vacuum_freeze_min_age 、 vacuum_freeze_table_age 设置为0。该模式下Full参数指定是多余的,该操作执行消耗同样是比较大的,且耗时的。

VACUUM VERBOSE
执行期间不需要获取对应表的独占锁,允许其他客户端的并发读写操作。该模式下仅仅会将dead tuple空间进行回收并释放给数据库,并不会释放给操作系统,vacuum期间打印每张表详细的垃圾回收记录。

VACUUM ANALYZE
执行期间不需要获取对应表的独占锁,允许其他客户端的并发读写操作,执行完毕vacuum后会再次执行analyza重新采集相关表的统计信息。该模式下仅仅会将dead tuple空间进行回收并释放给数据库,并不会释放给操作系统。

VACUUM INDEX_CLEANUP ON
默认情况下,vacuum会跳过index vacuum, 当INDEX_CLEANUP  设置为ON时,vacuum 在释放表和索引的dead tuple。

更多参数说明参考官方手册: https://www.postgresql.org/docs/current/sql-vacuum.html


使用示例:
vacuum (analyze,verbose,index_cleanup on) test_tab;

 

posted @ 2025-06-17 15:27  屠魔的少年  阅读(34)  评论(0)    收藏  举报