AutoVacuum系统自动清理进程

AutoVacuum系统自动清理进程
在PostgreSQL数据库中,对表元组的UPDATE或DELETE操作并未立即删除旧版本的数据,表中的旧元组只是被标识为删除状态,并未立即释放空间。这种处理对于获取多版本并发控制是必要的,如果一个元组的版本仍有可能被其他事务看到,那么就不能删除元组的该版本。当事务提交后,过期元组版本将对事务不再有效,因而其占据的空间必须回收以供其他新元组使用,以避免对磁盘空间增长的无休止的需求,此时对数据库的清理工作通过运行VACUUM来实现。
PostgreSQL数据库引入的可选辅助进程AutoVacuum(系统自动清理进程),自动执行VACUUM和ANALYZE命令,回收被标识为删除状态记录的空间,更新表的统计信息。
在PostgreSQL数据库系统配置文件中,与系统自动清理相关的主要相关参数如下:
autovacuum:是否启动系统自动清理功能,默认值为on。
autovacuum_max_workers:设置系统自动清理工作进程的最大数量。
autovacuum_naptime:设置两次系统自动清理操作之间的间隔时间。
autovacuum_vacuum_threshold和autovacuum_analyze_threshold:设置当表上被更新的元组数的阈值超过这些阈值时分别需要执行vacuum和analyze。
autovacuum_vacuum_scale_factor和autovacuum_analyze_scale_factor:设置表大小的缩放系数。
autovacuum_freeze_max_age:设置需要强制对数据库进行清理的XID上限值。

AutoVacuum系统自动清理进程中包含两种不同的处理进程:
AutoVacuum Launcher和AutoVacuum Worker。
AutoVacuum Launcher进程为监控进程,用于收集数据库运行信下息,根据数据库选择规则选中一个数据库,并调度下一个AutoVacuum Worker进程执行清理操作。
在AutoVacuum Launcher进程中,选择数据库的规则如下:首先由于数据库事务XID是32位整数且递增分配,当超过最大值时会从头开始计数使用,而事务XID的大小表示事务开始的时间,事务XID重新计数使用会使数据库中部分事务数据丢失,因此当XID超过配置的autovacuum_freeze_max_age时,强制对该数据库进行清理并更新事务XID;其次,若无强制清理操作,则选择数据库列表中最早未执行过自动清理操作的数据库。Launcher进程会定时(或者被信号驱动)选择数据库并调度Worker进程去执行清理工作。

AutoVacuum中的AutoVacuum Worker进程执行实际的清理任务,Launcher进程中维护有Worker进程列表。Worker进程列表由三种不同状态的进程列表构成,即空闲的Worker进程列表、正在启动的Worker进程、运行中的Worker进程列表。Launcher进程在不同状态之间的切换实现了Worker进程的调度工作。

首先,在初始化阶段创建的运行内存上下文中,创建长度为autovacuum_max_workers的空闲Worker进程描述信息列表,而正在启动Worker进程和运行中的Worker进程的列表被置为空。如果Launcher进程需要一个Worker进程,空闲Worker进程列表不为空且当前没有正在启动中的Worker进程,则开始一个启动Worker进程的操作,即向Postmaster进程发送启动消息,从空闲Worker进程列表中取出一个进程描述信息,设置为启动中状态。
Launcher进程中只允许存在一个启动中状态的Worker进程,启动中的Worker进程如果超时(超时时间由autovacuum_naptime设置)将被取消并重新开始启动Worker进程的循环。如果Worker启动成功,将启动成功的Worker进程信息添加到运行中的Worker进程列表中。运行中的Worker进程即连接上根据规则选中的数据库。

在系统进行自动清理的同时,用户可以使用安装目录bin文件夹下的vacuumdb或者vacuumlo工具对数据进行手动清理工作。vacuumdb工具清理数据库并对数据库执行分析操作,vacuumlo工具清理数据库中无效的大对象。

 

------翻译自官方 https://www.postgresql.org/docs/9.4/static/routine-vacuuming.html

在“自动清理守护进程”实际上是由多个进程。有一个持久的守护进程,称为autovacuum启动程序,负责启动所有数据库的autovacuum工作进程。启动程序将跨时间分配工作,尝试在每个autovacuum_naptime 秒内启动每个数据库中的一个工作程序。(因此,如果安装具有N个数据库,则每个autovacuum_naptime / Nseconds将启动一个新工作程序。)允许最多 同时运行autovacuum_max_workers工作进程。如果有超过autovacuum_max_workers要处理的数据库,第一个工作完成后,将立即处理下一个数据库。每个工作进程将检查其数据库中的每个表,并根据需要执行VACUUM 和/或ANALYZE。log_autovacuum_min_duration可用于监视autovacuum活动。正在运行的worker的数量不计入max_connections 或 superuser_reserved_connections限制。

在启动成功的Worker进程连接数据库成功后,将遍历该数据库中的表,根据对表的清理规则选择要执行的表和在该表上执行的操作。对表的操作分为VACUUM和ANALYZE两种,对选中的表如果上次VACUUM之后的过期元组的数量超过了“清理阈值”(vacuum threshold),那么就清理该表,清理阈值是定义为:

vacuum threshold = vacuum base threshold + vacuum scale factor * number of tuples

清理阈值=清理基本阈值+清理缩放系数 *元组数

这里的清理基本阈值是autovacuum_vacuum_threshold,清理的缩放系数是autovacuum_vacuum_scale_factor,元组的数目可以从统计收集器里面获取。这是一个部分精确的计数,由每次UPDATE和DELETE操作更新。

如果表上次被执行ANALYZE操作之后,其中过期元组的数量超过了“分析阈值”(analyze threshold),那么就分析该表更新表统计信息,分析阈值的定义与清理阈值相似,定义如下:

analyze threshold = analyze base threshold + analyze scale factor * number of tuples

分析阈值=分析基本阈值+分析缩放系数 *元组数目

缺省的阈值和伸缩系数都是从postgresql.conf里面取得的。不过,我们可以以每个表独立设置的方式覆盖它,方法就是在系统表pg_autovacuum里输入信息。pg_autovacuum表中一个元组可以用来记录一个需要自动清理的表及其清理设置,AutoVacuum进程将使用其中的清理设置来清理该表。如果没有特别设置该表的清理设置,AutoVacuum将使用全局设置。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值