在我们了解如何调整 PostgreSQL Auto-vacuum之前,让我们简要了解一下 PostgreSQL 中VACUUM 的重要性。
为什么需要 Autovacuum?
在 PostgreSQL 中,被删除或修改的行并没有完全删除。相反,它们被标记为死元组。换句话说,PostgreSQL 不会物理删除这些行,而是在它们上放置一个标记,以防止将来的查询返回或访问死元组。
死元组消耗存储空间,导致数据库膨胀。数据库臃肿是数据库服务器性能不佳的主要原因之一(不包括其他架构原因)。为了防止死行占用过多的存储空间,我们需要运行一个后台进程来恢复死行或元组占用的存储空间。
PostgreSQL 提供了删除死行或元组的VACUUM命令和VACUUM ANALYZE命令。但是,这两个命令的操作方式不同。
VACUUM命令仅关注删除死行以恢复存储空间,同时VACUUM ANALYZE命令删除死行占用的存储空间,并更新查询计划器使用的统计信息以选择或选择执行查询的最有效计划。
还有其他参数,例如FULL, FREEZE, DISABLE_PAGE_SKIPPING,我们可以对PostgreSQL中的表级别运行VACUUM任务。
PostgresqL文档(https://www.postgresql.org/docs/13/runtime-config-autovacuum.html)包含用于自定义清理任务的附加参数。
可见性映射在VACUUM 处理中的作用
早于 8.4 版的 Postgres 版本在清理死元组方面表现不佳。通过以下步骤对表进行清理:
- Postgres 扫描所有表以获取所有死元组并在必要时冻结旧元组。
- 删除指向相应死元组的索引元组。
- 删除死元组、更新活动元组、清理索引和更新表统计信息。
然而,可见性映射的引入改进了 Postgresql 中的VACUUM 处理。可见性映射确定表文件中的每个页面是否有死元组。VACUUM 处理会跳过没有死元组的页面。在这种情况下不需要扫描表。
配置 Postgres Autovacuum相关参数
让我们讨论如何在 PostgreSQL 中使用以下参数适当地调整Autovacuum。
auto_vacuum:此参数是布尔类型:ON或OFF。默认值为ON。在这种情况下,服务器启动autovacuum守护程序。此外,PostgreSQL建议必须启用track_counts参数才能使Autovacuum正常工作。
track_counts 参数允许收集有关数据库活动的统计信息。
即使您决定设置auto_vacuum为OFF,如果迫切需要阻止事务环绕 ID,PostgreSQL 也会启动一个Autovacuum进程。
log_autovacuum_min_duration :在指定的时间内记录清理任务。如果要跟踪或记录 autovacuum 任务的活动,此参数很有帮助。例如,您想检查是否有一个 autovacuum 任务由于不存在的关系而没有运行或执行。设置值以-1记录此类信息。
autovacuum_max_workers : autovacuum workers/进程与autovacuum 启动器不同。autovacuum启动器查找需要清理的表/关系,然后启动Autovacuum 工作程序以处理选定的表/关系。根据分配给此参数的 INTEGER 值,假设有四个worker。启动器启动四个worker在选定的表上工作。autovacuum_max_workers的默认值为3。如果您正在处理许多死元组,我们建议您增加worker的数量以加速VACUUM处理。否则,默认值是可以的。
autovacuum_naptime : 这个参数定义了 autovacuum 启动器的休眠时间。因此,假设我们希望启动器每两分钟检查一次数据库以发出VACUUM和ANALYZE,我们可以将的autovacuum_naptime整数值设置为2。设置适当的休眠时间可以防止与其他后台 Postgres 进程争用资源,因为VACUUM处理是定期初始化的。请注意,此参数与 autovacuum worker 无关,而是与启动器相关。
autovacuum_vacuum_threshold:此参数定义了在 PostgreSQL 表上触发VCACUUM命令的阈值。所以假设你想VACUUM用 100 个死元组触发命令表。您可以将整数值设置为 100。默认值为 50 个已删除/更新的元组/行。此参数指定删除/更新元组/行的最小阈值。
当dead_tuple超过autovacuum_vacuum_scale_factor×表上记录+autovacuum_vacuum_threshold的时候就会触发对表的vacuum
autovacuum_vacuum_insert_threshold: 这个参数类似autovacuum_vacuum_threshold。唯一的区别是插入元组/行而不是更新/删除的行/元组。默认值为 1000 个元组。但是,如果指定了 -1,autovacuum 将不会VACUUM在任何选定的表上启动命令。如果有足够的资源可用于清理,您可以增加autovacuum_vacuum_insert_threshold参数的值。如果不是的话,我们建议您不要调整默认值。
autovacuum_analyze_threshold:此参数指定在选定表上启动或触发ANALYZE命令的插入、更新或删除元组的最小或最少数量。默认值为 50 个元组/行。
假设您的 Postgres 服务器运行在具有多个更快内核的平台上,建议增加默认值让ANALYZE频繁运行或执行命令,因为查询计划器依赖于ANALYZE命令产生的统计结果来选择最有效的查询执行计划。因此,如果pg_statistic系统目录中的结果不是最新的,则查询计划器无法为查询选择最有效的执行计划。
autovacuum_vacuum_scale_factor:此参数基本上指定了决定何时触发VACUUM命令的表大小的一部分。它被添加到参数autovacuum_vacuum_threshold中。默认值 20% 是可选的,适用于处理速度最低的数据平台。
autovacuum_vacuum_insert_scale_factor:这个参数和我们之前讨论的参数类似。唯一的区别是这个参数被添加到autovacuum_vacuum_insert_threshold参数而不是autovacuum_vacuum_threshold参数中。
autovacuum_analyze_scale_factor:此参数指定包含在autovacuum_analyze_threshold参数中的表大小的一部分,以决定何时执行ANALYZE命令。默认值为 0.1 或 10%。同样,如果 Postgres 在多核服务器上运行,建议增加默认值,因为更新的统计信息可以提高查询性能。
autovacuum_freeze_max_age:此参数指定pg_class.relfrozenxid列的最大值,以防止表内的事务回绕。该VACUUM命令被执行或触发以冻结旧行或将旧行转换为冻结行该事务的默认值是2亿个事务。我们建议默认值适用于大多数情况。
autovacuum_multixact_freeze_min_age:此参数与我们刚刚讨论的上一个参数相似,但它侧重于在触发命令之前 multixact 的最小值,VACUUM以防止表内的 multixact ID 回绕。此参数的默认值为 4 亿个 mutlixact。
请注意,multixact在 Postgres 中是指多个事务同时锁定一行。
autovacuum_vacuum_cost_delay:该参数用于防止autovacuum worker超出参数指定的工作点autovacuum_vacuum_cost_limit。建议不要增加此参数的值,以防止worker过度消耗操作系统资源,避免资源争用。
autovacuum_vacuum_cost_limit:此参数可防止 autovacuum worker 消耗过多的可用操作系统资源。如果您正在处理大表,建议将参数的值设置为 0,以避免表膨胀。但是,如果您正在处理小表,则可以将其设置为 -1,以允许其他 cpu 内核专注于其他高优先级处理任务。
我们不建议您严格按照上述说明为 PostgreSQL 调整 autovacuum。但是,您可以使用这些步骤来了解 autovaccum 在 PostgreSQL 中的工作原理,并根据自己的喜好对其进行调整。
结论
正确配置 autovacuum 对于避免死元组导致性能下降很重要。如果您需要有关正确调整它的建议,请考虑我们的PostgreSQL Health Check。(https://vettabase.com/blog/services/health-checks/postgresql/)
原文链接:https://vettabase.com/blog/tuning-postgresql-auto-vacuum/?utm_source=rss&utm_medium=rss&utm_campaign=tuning-postgresql-auto-vacuum
作者:Michael Aboagye
译者:阎书利