PostgreSQL13优化AUTOVACUUM说明
PostgreSQL13的AUTOVACUUM机制自动清理死元组、更新统计信息并冻结事务ID。对于10个以上数据库的实例,需优化默认参数(如增加worker数量、调整清理频率)。当数据库超过200个时,建议延长清理间隔并配合夜间定时脚本执行VACUUM ANALYZE操作。脚本会分析各数据库死元组数量,对超标数据库进行清理,避免影响日间性能。这种组合方案能平衡资源占用与清理效率。
·
在PostgreSQL13中AUTOVACUUM是数据库中的自动清理机制,主要作用是在后台自动执行VACUUM操作:
- 清理死元组:自动删除已删除或更新后产生的旧版本数据,释放存储空间
- 更新统计信息:更新表的统计信息,帮助查询优化器生成更优的执行计划
- 冻结事务ID:防止事务ID回卷问题,确保数据库长期稳定运行
PostgreSQL13的AUTOVACUUM默认是开启的,但实际应中当PostgreSQL13在单实例数据库数量超过10个的情况下(也需要考虑单库大小)即需要优化默认参数,否则就会造成AUTOVACUUM无法及时清理死元组或更新统计信息,造成数据库访问变慢,具体推荐优化参数如下:
autovacuum_max_workers = 10
autovacuum_naptime = 45s
autovacuum_vacuum_scale_factor = 0.03
autovacuum_analyze_scale_factor = 0.02
autovacuum_vacuum_cost_limit = 2000
autovacuum_vacuum_cost_delay = 3ms

当数据库数量超过200个以,以上配置可能会造成CPU资源占用过高,可以将自动清理时间设置长一些,比如:autovacuum_naptime = 120min,这样可以把AUTOVACUUM的CPU占用降下来,但是会造成AUTOVACUUM不能及时自动清理,需要借助脚本定时完成手动清理。脚本执行可以在夜间数据库访问量低时执行,比如夜间12点开始:
0 0 * * * /home/cron_task/vacuumanalyze/dead_tup.sh
#!/bin/bash
# 你可以根据需要修改数据库用户名和密码
PGUSER="postgres" # 数据库用户名
PGPASSWORD="password" # 数据库密码(如果有)
# 获取所有数据库列表(排除模板库)
databases=$(PGPASSWORD=$PGPASSWORD psql -h 127.0.0.1 -U $PGUSER -d postgres -t -c "SELECT datname FROM pg_database WHERE datname NOT IN ('template0', 'template1');")
# 清空 db.list 文件
> dead_tup_db.list
# 循环处理每个数据库
for db in $databases; do
echo "正在处理数据库: $db"
# 执行 ANALYZE,确保统计信息是最新的
echo "正在对数据库 $db 执行 ANALYZE..."
PGPASSWORD=$PGPASSWORD psql -h 127.0.0.1 -U $PGUSER -d "$db" -c "ANALYZE;"
# 执行查询死元组的脚本
result=$(PGPASSWORD=$PGPASSWORD psql -h 127.0.0.1 -U $PGUSER -d "$db" -t -c "
SELECT SUM(n_dead_tup)
FROM pg_stat_user_tables;
")
# 如果死元组大于1000,输出数据库名称到 dead_tup_db.list 文件,并执行 VACUUM ANALYZE
if [[ $(echo "$result" | xargs) -gt 1000 ]]; then
echo "$db" >> dead_tup_db.list
echo "正在对数据库 $db 执行 VACUUM ANALYZE..."
# 执行 VACUUM ANALYZE 命令
PGPASSWORD=$PGPASSWORD psql -h 127.0.0.1 -U $PGUSER -d "$db" -c "VACUUM ANALYZE;"
echo "数据库 $db 的 VACUUM ANALYZE 执行完毕"
fi
done
Ubuntu 22.04 8C16G SSD postgresql.auto.conf典型配置(实测此配置可以支持5000+库):
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
max_connections = '300'
shared_buffers = '4GB'
effective_cache_size = '12GB'
work_mem = '4MB'
wal_buffers = '-1'
checkpoint_completion_target = '0.9'
min_wal_size = '2GB'
max_wal_size = '8GB'
wal_compression = 'on'
default_statistics_target = '100'
random_page_cost = '1.1'
effective_io_concurrency = '200'
max_worker_processes = '8'
max_parallel_workers = '8'
max_parallel_workers_per_gather = '4'
max_parallel_maintenance_workers = '4'
autovacuum = 'on'
autovacuum_max_workers = '4'
autovacuum_naptime = '1min'
autovacuum_vacuum_scale_factor = '0.02'
autovacuum_vacuum_threshold = '500'
autovacuum_analyze_scale_factor = '0.05'
autovacuum_analyze_threshold = '200'
autovacuum_work_mem = '256MB'
log_autovacuum_min_duration = '30s'
log_checkpoints = 'on'
autovacuum_vacuum_cost_limit = '2000'
autovacuum_vacuum_cost_delay = '2ms'
maintenance_work_mem = '512MB'
logging_collector = on
log_min_duration_statement = 2000
log_statement = 'none'
log_duration = off
log_connections = off
log_disconnections = off
更多推荐
所有评论(0)