PostgreSQL码农集散地

PostgreSQL 18 preview - 优化insert only表的autovacuum freeze频率

PostgreSQL 18 preview - 优化insert only表的autovacuum freeze频率

如果一个数据库用于记录日志(泛时序场景), 只写表可能只有在年龄达到高龄才会触发freeze, 极端场景可能会引起因防止事务回卷导致的数据库故障(不允许写入).

为了解决这个问题, pg给出了优化, pg_class增加relallvisible, relallfrozen两个统计值, 在只有写入的情况下, relallvisible很高, relallfrozen则可能较低, 此时可以根据算法触发freeze.

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=99f8f3fbbc8f743290844e8c676d39dad11c5d5d

Add relallfrozen to pg_class  
author Melanie Plageman <[email protected]>   
Mon, 3 Mar 2025 16:18:05 +0000 (11:18 -0500)  
committer Melanie Plageman <[email protected]>   
Mon, 3 Mar 2025 16:18:05 +0000 (11:18 -0500)  
commit 99f8f3fbbc8f743290844e8c676d39dad11c5d5d  
tree bfa0507e88c83d28053a7e8beb36d8d61b43b871 tree  
parent 8492feb98f6df3f0f03e84ed56f0d1cbb2ac514c commit | diff  
Add relallfrozen to pg_class  

Add relallfrozen, an estimate of the number of pages marked all-frozen  
in the visibility map.  

pg_class already has relallvisible, an estimate of the number of pages  
in the relation marked all-visible in the visibility map. This is used  
primarily for planning.  

relallfrozen, together with relallvisible, is useful for estimating the  
outstanding number of all-visible but not all-frozen pages in the  
relation for the purposes of scheduling manual VACUUMs and tuning vacuum  
freeze parameters.  

A future commit will use relallfrozen to trigger more frequent vacuums  
on insert-focused workloads with significant volume of frozen data.  

Bump catalog version  

Author: Melanie Plageman <[email protected]>  
Reviewed-by: Nathan Bossart <[email protected]>  
Reviewed-by: Robert Treat <[email protected]>  
Reviewed-by: Corey Huinker <[email protected]>  
Reviewed-by: Greg Sabino Mullane <[email protected]>  
Discussion: https://postgr.es/m/flat/CAAKRu_aj-P7YyBz_cPNwztz6ohP%2BvWis%3Diz3YcomkB3NpYA--w%40mail.gmail.com  

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=06eae9e6218ab2acf64ea497bad0360e4c90e32d

Trigger more frequent autovacuums with relallfrozen  
author Melanie Plageman <[email protected]>   
Mon, 3 Mar 2025 19:42:00 +0000 (14:42 -0500)  
committer Melanie Plageman <[email protected]>   
Mon, 3 Mar 2025 19:42:00 +0000 (14:42 -0500)  
commit 06eae9e6218ab2acf64ea497bad0360e4c90e32d  
tree c9346e7a784ad9dcd4947c65bf6abadc24ada853 tree  
parent 35c8dd9e1176ae0c3cb060b0da9cb2bba925363c commit | diff  
Trigger more frequent autovacuums with relallfrozen  

Calculate the insert threshold for triggering an autovacuum of a  
relation based on the number of unfrozen pages.  

By only considering the unfrozen portion of the table when calculating  
how many tuples to add to the insert threshold, we can trigger more  
frequent vacuums of insert-heavy tables. This increases the chances of  
vacuuming those pages when they still reside in shared buffers  

This also increases the number of autovacuums triggered by tuples  
inserted and not by wraparound risk. We prefer to freeze these pages  
during insert-triggered autovacuums, as anti-wraparound vacuums are not  
automatically canceled by conflicting lock requests.  

We calculate the unfrozen percentage of the table using the recently  
added (99f8f3fbbc8f) relallfrozen column of pg_class.  

Author: Melanie Plageman <[email protected]>  
Reviewed-by: Nathan Bossart <[email protected]>  
Reviewed-by: Greg Sabino Mullane <[email protected]>  
Reviewed-by: Robert Treat <[email protected]>  
Reviewed-by: wenhui qiu <[email protected]>  
Discussion: https://postgr.es/m/flat/CAAKRu_aj-P7YyBz_cPNwztz6ohP%2BvWis%3Diz3YcomkB3NpYA--w%40mail.gmail.com  

+#autovacuum_vacuum_insert_scale_factor = 0.2   # fraction of unfrozen pages  
+          # before insert vacuum  

这两个 patch 都与 PostgreSQL 的 pg_class 表和自动清理(autovacuum)机制相关,主要目的是通过引入 relallfrozen 字段来优化自动清理的触发逻辑。以下是这两个 patch 的详细解读:


Patch 1: Add relallfrozen to pg_class

背景

PostgreSQL 的 pg_class 表中已经有一个字段 relallvisible,用于记录关系(表或索引)中所有可见页面的估计数量。这个字段主要用于查询计划优化。然而,relallvisible 并不区分页面是否被冻结(frozen),而冻结页面是防止事务 ID 回绕(wraparound)的关键。

改动内容

  1. **新增字段 relallfrozen**:

  • 该 patch 在 pg_class 表中新增了一个字段 relallfrozen,用于记录关系中所有冻结页面的估计数量。
  • relallfrozen 与 relallvisible 结合使用,可以更好地估计关系中“可见但未冻结”的页面数量。
  • 用途:

    • 该字段的主要用途是帮助调度手动清理(VACUUM)和调整冻结参数。
    • 未来可以通过 relallfrozen 来触发更频繁的清理操作,特别是在插入密集型工作负载中,冻结数据量较大的情况下。
  • 目录版本更新:

    • 由于 pg_class 表的结构发生了变化,该 patch 还更新了目录版本(catalog version)。

    Patch 2: Trigger more frequent autovacuums with relallfrozen

    背景

    自动清理(autovacuum)是 PostgreSQL 中用于维护表健康的重要机制。当前的自动清理触发逻辑主要基于插入的元组数量,但并未充分考虑冻结页面的情况。这可能导致插入密集型工作负载中,冻结页面未能及时清理,从而增加事务 ID 回绕的风险。

    改动内容

    1. 基于未冻结页面的插入阈值计算:

    • 该 patch 修改了自动清理的触发逻辑,使其在计算插入阈值时,仅考虑未冻结页面的数量。
    • 通过这种方式,可以更频繁地触发自动清理,特别是在插入密集型工作负载中。
  • 使用 relallfrozen 字段:

    • 该 patch 利用 pg_class 表中新增的 relallfrozen 字段,计算表中未冻结页面的比例。
    • 这种计算方式使得自动清理能够更精确地针对需要冻结的页面。
  • 优化清理时机:

    • 通过更频繁地触发自动清理,可以增加在共享缓冲区(shared buffers)中清理页面的机会,从而减少 I/O 开销。
    • 此外,这种优化还减少了因事务 ID 回绕风险而触发的清理操作,因为事务 ID 回绕清理无法被锁请求自动取消。

    总结

    这两个 patch 的核心目标是通过引入 relallfrozen 字段和优化自动清理触发逻辑,提升 PostgreSQL 在插入密集型工作负载中的性能和数据健康管理能力。具体来说:

    1. Patch 1 新增了 relallfrozen 字段,用于记录关系中冻结页面的估计数量。
    2. Patch 2 利用 relallfrozen 字段优化了自动清理的触发逻辑,使其能够更频繁地清理未冻结页面,从而减少事务 ID 回绕的风险。

    这些改动不仅提高了系统的稳定性,还优化了清理操作的效率,特别是在高插入负载的场景下。