PostgreSQL的AutoVacuum原理及autovacuum不工作问题解析

1、AutoVacuum概述

PostgreSQL数据库是有数据清理的,有人工执行清理,也有自动清理,但是这2种的清理方式对性能是有不同的影响,特别是OLTP环境中,每次不管是人工清理还是自动清理dead tuple,都会对数据库的IO有明显的影响,基于PostgreSQL 的原理每个表中的行会存在多个版本的数据,为了完成数据库的MVCC 多版本控制,以及数据的UNDO 的功能在这些过期版本的行被弃用后,会产生众多的死行dead tuple.在这样的情况下,如果不及时的将这些dead tuple 进行清理,轻则影响磁盘空间的在利用,重则影响数据库的性能,在测试中发现,在每次进行百万级别的dead tuple清理,数据库会有7%-10%的性能下降,多次往复亦是如此,同时会导致本来一张表3G的表就能存储,但最终由于dead tuple可能达到80G甚至更大的空间。

2、AutoVacuum参数说明

autovacuum

  • 默认:autovacuum = on  (布尔型)
  • 表示是否开起autovacuum。当需要冻结xid(事务ID)时,尽管此值为off,PG也会进行vacuum。

log_autovacuum_min_duration

  • 默认:log_autovacuum_min_duration = -1(数字型)       单位ms
  • 在规定时长内未完成的vacuum予以记录日志,-1表示禁用,0表示所有的,大于0仅记录超过时间的。

autovacuum_max_workers

  • 默认:autovacuum_max_workers = 3(数字型)
  • autovacuum最大工作清理进程数,CPU核多IO好的情况下,可以增加,但是注意内存消耗,有多少个worker就会有多少倍的autovacuum_work_mem内存使用,会消耗较多内存,重启数据库生效。

autovacuum_naptime

  • 默认:autovacuum_naptime = 1min(分钟)
  • 两次vacuum启动的时间间隔。

autovacuum_analyze_threshold

  • 默认:autovacuum_analyze_threshold = 50(数字型)
  • 自动analyze操作的最小行数,有利于对SQL语句进行更精准匹配到最好的执行计划。

autovacuum_vacuum_scale_factor

  • 默认:autovacuum_vacuum_scale_factor = 0.2(数字型)
  • autovacuum的vacuum操作所需的变更量阈值,这个表的update/delete的tuple总数大于(pg_class.reltuples*autovacuum_vacuum_scale_factor+autovacuum_vacuum_threshold)时, 触发vacuum操作,建议不要太高频率,否则会因为vacuum产生较多的XLOG。

autovacuum_analyze_scale_factor

  • 默认:autovacuum_analyze_scale_factor = 0.1(数字型)
  • 表示autovacuum的analyze操作所需的变更量阈值,当这个表的INSERT/update/delete的tuple总数大于(pg_class.reltuples*autovacuum_analyze_scale_factor+autovacuum_analyze_threshold)时, 触发analyze操作。

autovacuum_freeze_max_age

  • 默认:autovacuum_freeze_max_age = 200000000(数字型)
  • 某表的pg_class.relfrozenxid的最大值,如果超出此值则重置xid,冻结表的记录。如果启用了autovacuum_freeze_max_age参数,还会防止事务ID过多导致的老化问题

autovacuum_vacuum_cost_delay

  • 默认:autovacuum_vacuum_cost_delay = 20ms (数字型)
  • 当autovacuum进程执行时,对vacuum执行cost进行评估,如果超过autovacuum_vacuum_cost_limit的值时,则延迟这么长的时间。

autovacuum_vacuum_cost_limit

  • 默认:autovacuum_vacuum_cost_limit = -1  (数字型)
  • autovacuum进程的评估阀值,-1表示使用vacuum_cost_limit值,如果在执行 autovacuum进程期间评估的cost超过autovacuum_vacuum_cost_limit,则autovacuum进程则会休眠。

3、autovacuum不工作问题解析

(1)分析过程

 1.查看OS主机整体资源使用情况。

2.看具体SQL执行计划(explain)

3.查看表数据量以及表大小

4.查看pg_stat_all_tables视图的n_dead_tup、last_autovacuum列

5.查看运行pg_log下的运行日志

(2)产生原因
本次问题产生原因是物理复制槽无效后未被删除导致。

可能产生该问题得到原因如下:

1.无效的复制槽未被删除。

2.长事物。

3.本地回环网络接口不可访问。autovacuum launcher process和stats collector process进程需要通过本地回环网络接口收集统计信息。

4.大表导致autovacuum过慢,autovacuum包含vacuum操作和analyze操作对于大表两个操作都会慢。

(3)解决方案

1.无效的复制槽未被删除

select * from pg_replication_slots;#查询复制槽状态

select pg_drop_replication_slot('复制槽名');#删除无效复制槽

2.长事物

设置参数

idle_in_transaction_session_timeout (integer)

终止任何已经闲置超过这个参数所指定的时间(以毫秒计)的打开事务的会话。

这使得该会话所持有的任何锁被释放,并且其所持有的连接槽可以被重用,

它也允许只对这个事务可见的元组被清理。

通过命令杀掉,占用长事物会话

select * from pg_stat_activity; #查询会话状态

pg_terminate_backend() #终止会话

3.本地回环网络接口不可访问。

autovacuum launcher process和stats collector process 进程需要通过本地回环网络接口收集统计信息。

pg_isready -h localhost -p 5432 #检查localhost连通性

ifconfig检查本地回环网口是否正常

4.大表导致autovacuum过慢,autovacuum包含vacuum操作

和analyze操作对于大表两个操作都会慢。

a.使用表分区,降低autovacuum操作的数据集大小。

#降低大表的比例因子大小

b.ALTER TABLE 表名 SET (autovacuum_analyze_scale_factor = 值);

c.业务非繁忙期,定时执行vacuum。

4、autovacuum后空间回收原理

vacuum只清理死元组,不会回收空间,只有手动执行vacuum full时,才会收回空闲空间给操作系统。

如:表中有三条数据,大小有400M,出现严重表膨胀,执行autovacuum后,清理了死元组,但是400M的空间被回收,这是因为,死元组存储在这三条数据后,执行autovacuum会自动收回三条数据后面的空间,表大小是1M,如果死元组在这三条数据中间,执行autovacuum不会收回存储空间,这张表大小还是400M。

 

 

 

 

posted @ 2024-07-09 09:37  数据库集中营  阅读(200)  评论(0编辑  收藏  举报