不同“类型”的自动吸尘器有不同的性能特点吗?

mga*_*lgs 3 postgresql autovacuum

在监视我的数据库上的 autovacuum 活动时,我注意到标记为 的 autovacuum(to prevent wraparound)似乎比“常规” autovacuum 花费的时间更长。这让我开始尝试了解各种“种类”或 autovacuum 的性能/行为差异。

文档中,我确定了 autovacuum 可能VACUUM是一张桌子的几个不同原因:

  1. 该表具有需要冻结的旧事务 ( relfrozenxid > min(autovacuum_freeze_max_age, table.autovacuum_freeze_max_age)。这就是“ (to prevent wraparound)”自动真空。

  2. 自上次以来表中过时的元组数VACUUM超过“真空阈值”

还有其他我想念的吗?

手册VACUUM中似乎暴露的“攻击性”旋钮是FREEZEDISABLE_PAGE_SKIPPING。这些不同类型的 autovacuum 是否曾经使用过这些选项,如果是,什么时候使用?

Cra*_*ger 5

在监视我的数据库上的 autovacuum 活动时,我注意到标记为(以防止环绕)的 autovacuum 似乎比“常规” autovacuum 花费的时间更长。

这是可以预料的。他们必须做更多的工作。这些本质上是vacuum freeze由 autovacuum 运行的。

冻结元组意味着通过用特殊的固定值FrozenTransactionId(xid 3)替换它们的交易 ID,将它们标记为对所有当前和未来的交易可见。由于元组的 xmin 存储在磁盘上的元组中,这意味着每个尚未冻结并且是冻结候选的元组都需要修改。这通常会触发整页写入,因为元组通常是自上次检查点以来页面上的第一次修改,导致每页上第一个冻结元组的写入为 8k。(这也会使 WAL 膨胀,从而导致 PITR 备份、复制流等膨胀)。

PostgreSQL 9.6 及以下版本中的冻结真空不能跳过部分表;他们每次都必须扫描整张桌子,即使只有一小部分是冻结的候选者。

除非您将 autovacuum 调整为更积极地冻结,否则它往往会很晚才离开强制冻结,然后立即执行大量工作。这是有效的,因为我们不会多次扫描表,但昂贵,因为我们每次处理它时都会做很多工作。

当真空不冻结元组时,它仍然在做很多相同的工作。但它通常在每次通过时接触的页面数量要少得多,因为它只需要关心那些xmax由自提交的事务设置的 not-for-locking-only 的元组。具有这些元组的页面也更有可能在缓存中,因为它们最近被删除了,并且它们的任何 multixact 数据也更有可能在缓存中。

您可以通过以下方式更快地冷冻真空吸尘器:

  • 降低autovacuum_vacuum_cost_delay- 这将使 autovacuum 使用更多资源并使系统负载更多,但运行速度更快。

  • 降低autovacuum_freeze_max_age让他们更频繁地运行,每次做更少的工作。这总体上效率较低,因为每次都必须扫描整个表,在我们读取表时从操作系统缓冲区缓存中逐出页面。(Pg 使用环形缓冲区进行 seq 扫描,但操作系统通常不会)。但这意味着我们为每次传递执行更少的写入,并且每次传递花费的时间更少。

  • COPY使用在执行它或执行它FREEZE的同一事务中批量加载表的选项。以这种方式加载的元组从预冻结开始。(详见说明书)。TRUNCATECREATECOPY

  • 在批量加载表格后手动冻结表格,因此您可以在自己控制的时间支付冻结费用。

就我个人而言,我希望 normal VACUUMs(和 autovacuums)进行更多的机会性冻结;特别是,如果我们刚刚接触了页面上的项目指针数组以将一些元组标记为可用空间,我们可能应该在页面脏时扫描可冻结的元组。这将与 PostgreSQL 10 中的新冻结图代码配合得很好。


PostgreSQL 9.6 在冻结方面有一些重大改进,可以减少重复清理对表的影响,并使冻结成本更低。由于在可见性图中引入了冻结图功能,我们可以避免扫描整个表,跳过冻结的页面。请参阅提交 a892234 和 fd31cd265。

commit fd31cd265138019dcccc9b5fe53043670898bc9f
Author: Robert Haas <rhaas@postgresql.org>
Date:   Thu Mar 10 16:12:10 2016 -0500

    Don't vacuum all-frozen pages.

    Commit a892234f830e832110f63fc0a2afce2fb21d1584 gave us enough
    infrastructure to avoid vacuuming pages where every tuple on the
    page is already frozen.  So, replace the notion of a scan_all or
    whole-table vacuum with the less onerous notion of an "aggressive"
    vacuum, which will pages that are all-visible, but still skip those
    that are all-frozen.

    This should greatly reduce the cost of anti-wraparound vacuuming
    on large clusters where the majority of data is never touched
    between one cycle and the next, because we'll no longer have to
    read all of those pages only to find out that we don't need to
    do anything with them.

    Patch by me, reviewed by Masahiko Sawada.
Run Code Online (Sandbox Code Playgroud)

我认为 PostgreSQL 10 也正在进行工作,以完全避免需要修改磁盘上的元组以将它们标记为冻结,但找不到相关的邮件列表线程 atm。

  • 冻结图实际上是在 9.6 中发布的。无需等待版本 10。 (2认同)