合 PG中的autovacuum介绍
Tags: PGPostgreSQLallow_system_table_modsautovacuumautovacuum_enabledautovacuum_vacuum_cost_delayautovacuum_vacuum_scale_factorautovacuum_vacuum_thresholdvacuum_cost_limit
简介
PostgreSQL有一个可选的但是被高度推荐的特性autovacuum,它的目的是自动执行VACUUM
和ANALYZE
命令。当它被启用时,自动清理会检查被大量插入、更新或删除元组的表。这些检查会利用统计信息收集功能,因此除非track_counts被设置为true
,自动清理不能被使用。在默认配置下,自动清理是被启用的并且相关配置参数已被正确配置。
“自动清理后台进程”实际上由多个进程组成。有一个称为 自动清理启动器的常驻后台进程, 它负责为所有数据库启动自动清理工作者进程。 启动器将把工作散布在一段时间上,它每隔 autovacuum_naptime秒尝试在每个数据库中启动一个工作者 (因此,如果安装中有N
个数据库,则每 autovacuum_naptime
/N
秒将启动一个新的工作者)。 在同一时间只允许最多autovacuum_max_workers 个工作者进程运行。如果有超过autovacuum_max_workers
个数据库需要被处理,下一个数据库将在第一个工作者结束后马上被处理。 每一个工作者进程将检查其数据库中的每一个表并且在需要时执行 VACUUM
和/或ANALYZE
。 可以设置log_autovacuum_min_duration 来监控自动清理工作者的活动。
如果在一小段时间内多个大型表都变得可以被清理,所有的自动清理工作者可能都会被占用来在一段长的时间内清理这些表。这将会造成其他的表和数据库无法被清理,直到一个工作者变得可用。对于一个数据库中的工作者数量并没有限制,但是工作者确实会试图避免重复已经被其他工作者完成的工作。注意运行着的工作者的数量不会被计入max_connections或superuser_reserved_connections限制。
relfrozenxid
值比autovacuum_freeze_max_age事务年龄更大的表总是会被清理(这页表示这些表的冻结最大年龄被通过表的存储参数修改过,参见后文)。否则,如果从上次VACUUM
以来失效的元组数超过“清理阈值”,表也会被清理。清理阈值定义为:
1 | 清理阈值 = 清理基本阈值 + 清理缩放系数 * 元组数 |
其中清理基本阈值为autovacuum_vacuum_threshold, 清理缩放系数为autovacuum_vacuum_scale_factor, 元组数为pg_class
.reltuples
。
如果自上次清理以来插入的元组数量超过了定义的插入阈值,表也会被清理,该阈值定义为:
1 | 清理插入阈值 = 清理基础插入阈值 + 清理插入缩放系数 * 元组数 |
清理插入基础阈值为autovacuum_vacuum_insert_threshold,清理插入缩放系数为autovacuum_vacuum_insert_scale_factor。 这样的清理可以允许部分的表被标识为all visible,并且也可以允许元组被冻结,可以减小后续清理的工作需要。 对于可以接收INSERT
操作但是不能或几乎不能UPDATE
/DELETE
操作的表, 可能会从降低表的autovacuum_freeze_min_age中受益,因为这可能允许元组在早期清理中被冻结。 废弃元组的数量和插入元组的数量可从统计收集器中获得;它是一个半精确的计数,由每个UPDATE
、DELETE
和 INSERT
操作进行更新。 (它只是半精确的,因为一些信息可能会在重负载情况下丢失。) 如果表的relfrozenxid
值大于vacuum_freeze_table_age
事务老的, 执行一个主动的清理来冻结旧的元组,并推进relfrozenxid
;否则,只有上次清理以后修改过的页面被扫描。
对于分析,也使用了一个相似的阈值:
1 | 分析阈值 = 分析基本阈值 + 分析缩放系数 * 元组数 |
该阈值将与自从上次ANALYZE
以来被插入、更新或删除的元组数进行比较。
临时表不能被自动清理访问。因此,临时表的清理和分析操作必须通过会话期间的SQL命令来执行。
默认的阈值和缩放系数都取自于postgresql.conf
,但是可以为每一个表重写它们(和许多其他自动清理控制参数), 详情参见Storage Parameters。 如果一个设置已经通过一个表的存储参数修改,那么在处理该表时使用该值,否则使用全局设置。 全局设置请参阅第 20.10 节。
当多个工作者运行时,在所有运行着的工作者之间自动清理代价延迟参数 (参阅第 20.4.4 节)是 “平衡的”,这样不管实际运行的工作者数量是多少, 对于系统的总体 I/O 影响总是相同的。不过,任何正在处理已经设置了每表 autovacuum_vacuum_cost_delay
或 autovacuum_vacuum_cost_limit
存储参数的表的工作者不会被考虑在均衡算法中。
autovacuum工作进程通常不会阻止其他命令。如果某个进程尝试获取与autovacuum持有的SHARE UPDATE EXCLUSIVE
锁冲突的锁,则锁获取将中断该autovacuum。有关冲突的锁定模式,请参见表 13.2。 但是,如果autovacuum正在运行以防止事务ID回卷(即在pg_stat_activity
视图中的autovacuum查询名以(to prevent wraparound)
结尾),则autovacuum不会被自动中断。
触发条件
根据postgresql.conf相关配置,理解autovacuum会在两种情况下会被触发: