在postgresql中打开和关闭autovacuum

翻译自:https://www.cybertec-postgresql.com/en/enabling-and-disabling-autovacuum-in-postgresql/

在postgresql中打开和关闭autovacuum

Hans-Jürgen Schönig发布于2021-06-02

Autovacuum 长期以来一直是 PostgreSQL 的一部分。但它是如何真正工作的呢?您可以简单地打开和关闭它吗?人们不断问我们这些关于启用和禁用autovaccum的问题。PostgreSQL依靠MVCC来处理多用户环境中的并发性。处理并发事务时出现的问题是必须清理死元组。在PostgreSQL中,这是由VACUUM 命令处理的,我们已经在其他一些帖子中介绍了它。但是,手动运行vacuum已成为过去。大多数人依靠PostgreSQL autovacuum守护进程来处理清理。

autovacuum怎么工作的?

首先要了解的是,autovacuum确实做到了它所说的:基本上,它是围绕手动vacuum的自动化。它所做的只是睡眠一会儿,并定期检查表是否需要处理。autovacuum需要注意三件事:

  • 为 PostgreSQL 优化器(ANALYZE)创建统计信息
  • 清理死元组
  • 处理回卷保护

在PostgreSQL中,autovacuum 是一个始终存在的服务器端守护进程。是的,没错:总是。即使您在 postgresql.conf 中关闭了 autovacuum (或使用 ALTER SYSTEM 调整 postgresql.auto.conf),根据设计——守护进程仍然会存在以帮助回卷保护。

autovacuum的工作方式是:它定期检查是否需要完成工作,并在需要启动新workers来照顾表时通知postmaster。Autovacuum不会直接启动工作线程,而是postmaster间接工作,以确保所有进程都在一个level上。它通过postmaster对系统更加可靠有显著帮助。
让我们仔细看看autovacuum的作用。

autovacuum创建优化器统计信息

PostgreSQL优化器在很大程度上依赖于统计数据。它估算各种操作返回的行数,并尝试猜测优化查询的最佳路径。

为此,需要使用表中数据的统计信息。如果表的内容发生更改,优化程序必须使用过时的统计信息,这反过来又会导致性能不佳。

因此,autovacuum会定期启动以更新所有统计数据。Autovacuum 依赖于各种配置参数(可在 postgresql.conf 中找到),可以更改这些参数以优化此行为:

autovacuum_analyze_threshold = 50 
# min number of row updates before analyze
autovacuum_analyze_scale_factor = 0.1 
# fraction of table size before analyze

这些参数将告诉autovacuum何时创建新统计信息。在上述情况下,规则如下:

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

默认配置下,autovacuum通常可以很好地自动维护统计信息。但是,有时有必要进行一些更精确的控制:

test=# CREATE TABLE t_foo (id int) WITH (autovacuum_analyze_scale_factor = 0.05);
CREATE TABLE
test=# \d+ t_foo
Table "public.t_foo"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+---------+--------------+-------------
id | integer | | | | plain | |
Access method: heap
Options: autovacuum_analyze_scale_factor=0.05

在这个例子中,autovacuum_analyze_scale_factor调整为0.05,以使autovacuum更具侵略性。这是必要的——特别是当表非常非常大。

autovacuum清理死元组

创建新的优化器统计信息非常重要。然而,还有更多重要的事情:清理死元组。一般来说,VACUUM 的目的是确保从堆和索引中很好地删除死元组。我们过去曾写过大量关于vacuum和清理的文章。

通常,默认设置是可以的。但是,就像在 ANALYZE 的情况下一样,调整这些参数以使自动真空守护程序更具侵略性或使其以更轻松的方式运行是有意义的。

设置autovacuum参数可以在创建表时默认使用全局参数(查看 postgresql.conf 或 postgresql.auto.conf),也可以在建表后完成,如下一个表所示:

test=# ALTER TABLE t_foo 
SET (autovacuum_vacuum_scale_factor = 0.4);
ALTER TABLE

在本例中,我们更改了scale factor,并降低了autovacuum的频率。

扫描二维码关注公众号,回复: 15360856 查看本文章

autovacuum处理事务回卷

autovacuum还有第三件事:它可以防止事务回卷。如果你想了解更多关于这个主题的信息,你也可以看看我关于PostgreSQL中的回卷保护的文章
在这里插入图片描述

事务回卷保护是一件重要的事情,不能掉以轻心;它可能会导致严重的停机时间,并导致各种工作负载出现问题。

打开和关闭autovacuum

autovacuum可以全局关闭。但是,这并不意味着守护程序已停止 - 它表示它仅执行回卷保护。这样做的原因是尽可能减少停机时间。忍受表膨胀比忍受停机时间更容易。

因此,停止autovacuum实际上是不可能的——它只能针对暂停大多数任务。无论如何,完全关闭autovacuum并不是一个好主意。在大多数情况下,关闭它只会造成麻烦。

有意义的是在单个表的特殊情况下禁用autovacuum。下面是一个可能有意义的场景:

  • 已创建表
  • 大量数据加载到表中
  • 进行修改和更正(更新、删除)
  • 执行聚合并将其存储在其他位置
  • 表立即或第二天被扔掉

在这种情况下,为什么有人会关心回卷,清理等?明明一张表还是被扔掉了,为什么要清理呢?请记住:我们在这里谈论的是非常具体的场景,我们绝对不是在谈论通用表。

以下是为单个表打开和关闭autovacuum的方法:

test=# ALTER TABLE t_foo SET (autovacuum_enabled = off);
ALTER TABLE
test=# ALTER TABLE t_foo SET (autovacuum_enabled = on);
ALTER TABLE

请理解,关闭autovacuum肯定不是一个好主意,除非您面对一个特定的用例,并且有充分的理由这样做。

手动vacuum和自动vacuum

如果autovacuum正在运行,但有人启动手动vacuum会发生什么?一般规则是:autovacuum总是失败的。如果您启动了 VACUUM 但已经有一个autovacuum正在运行,PostgreSQL 将终止worker进程并为您的手动进程提供优先级。

几乎所有其他操作也是如此。假设有人想要删除一列、一个表等。如果发生冲突,PostgreSQL 将总是终止autovacuum进程,并确保后台操作不会损害正常的用户操作。

为什么autovacuum这么慢

许多人一直在问为什么autovacuum比手动vacuum慢。首先,在默认配置中,autovacuum确实比手动vacuum慢得多。原因是通常称为成本延迟:

test=# SHOW autovacuum_vacuum_cost_delay;
autovacuum_vacuum_cost_delay
------------------------------
2ms

当 VACUUM 表时,它通常会“全速”进行,这意味着清理表可能会导致大量的 I/O 瓶颈。单个 VACUUM 作业每秒可能会消耗数百兆的 I/O,这为其他操作留下了更少的流量,进而可能导致响应时间不佳。

解决方案是autovacuumI/O惩罚,并为进程添加的设定延迟。处理表将花费更长的时间,但它会导致较低对其他进程的总体影响。在旧版本的PostgreSQL中,设置为20毫秒。但是,在PostgreSQL 13及更高版本中,它已减少到2毫秒。

设定延迟(可以基于每个表关闭)是最终用户观察到运行时差异的核心原因。

最后···

如果您想了解更多关于PostgreSQL性能的信息,我们还建议您查看我们的咨询服务。我们帮助您调整数据库并确保您的服务器正常运行。

猜你喜欢

转载自blog.csdn.net/qq_40687433/article/details/130774352