首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >PG 19 Vacuum 又提速了

PG 19 Vacuum 又提速了

作者头像
用户4035096
发布2026-07-10 09:08:32
发布2026-07-10 09:08:32
40
举报

PG 19 Vacuum 又提速了

PostgreSQL 又砍掉一笔“隐形税”:这个 VACUUM 小改动,为什么值得所有 DBA 和开发者重视?

很多系统,不是慢在 SQL,不是慢在磁盘,而是慢在一堆“本来就不用做”的后台动作上。 PostgreSQL 最新这个 commit,砍的就是这种最容易被忽视、却会长期吞噬维护成本的“隐形税”。

先说结论:这不是一个“VACUUM 大提速”的营销型优化,而是一个非常典型的 PostgreSQL 式内核优化:让明知没有收益的工作,直接别发生。

这次提交 01b7e4a46d0fa8478c1142f65ee441fb0c32cca1 做的事情很克制,但很值钱。 提交信息已经把问题说透了:

  • 因为 SKIP_PAGES_THRESHOLD 这类扫描策略优化
  • 或者因为 stale prune XID
  • heap_page_prune_and_freeze() 可能会被调用到一些实际上根本没有 pruning/freezing 工作可做的页面上

于是新逻辑加了一个 fast path:

  • 如果页面已经是 all-frozen,直接早退
  • 或者页面已经是 all-visible,并且这轮不会尝试 freezing,也直接早退
  • 但如果 VACUUM 明确传了 DISABLE_PAGE_SKIPPING,那就不能这么干

这就是典型的 PostgreSQL 优化哲学: 不是拼命把“必要工作”做快,而是优先识别“不必要工作”,然后一刀砍掉。

为什么这件事重要?

因为数据库系统真正昂贵的,不只是执行器里的前台 SQL。 后台维护同样在抢资源,而且是持续抢:

  • 抢 CPU
  • 抢缓存命中机会
  • 抢 I/O 调度窗口
  • 抢锁与并发处理预算

从第一性原理看,只要一个动作不产生收益,它就应该被消灭。 哪怕它单次只浪费一点点判断、检查、函数调用、页级处理路径开销,乘上:

  • 大表
  • 高频 autovacuum
  • 长周期运行
  • 大量冷热分层数据

它就会变成一笔稳定复利的系统性成本。

所以这次改动真正优化的,不是“SQL 跑得更快”,而是维护路径更不浪费

先把两个概念说清楚:all-visible 不等于 all-frozen

很多人嘴上都说知道 visibility map,但真到讨论 VACUUM 行为时,概念经常混。

PostgreSQL 的 visibility map,对每个 heap page 维护 2 个 bit

  • all-visible
  • all-frozen

这两个 bit 的意义完全不同。

all-visible 是什么?

表示这个页面上的 tuple 对所有事务都可见。 这意味着:

  • VACUUM 可以跳过它,不必再为“清理死元组”浪费时间
  • index-only scan 更容易成立,因为可以少回表检查可见性

all-frozen 又是什么?

这是更强的状态。 表示这个页面上的 tuple 不只是“都可见”,而且都已经冻结。 而且它只能建立在 all-visible 基础上。

这有什么价值? 价值在于:即便是为了防止 XID wraparound 的 aggressive VACUUM,也可以跳过这些页面。

一句话概括:

  • all-visible 解决的是“要不要看这个页”
  • all-frozen 解决的是“连防腐式的大扫除都可以不看这个页”

关键误区:可跳过,不等于永远不会访问

这正是这次 commit 值得写文章的地方。

很多人以为,只要页面被标成 all-visibleall-frozen,VACUUM 就一定不会碰。 错。

PostgreSQL 为了整体扫描效率,并不是机械式“见到可跳过页就跳”。

第一种情况:SKIP_PAGES_THRESHOLD

代码里有一个非常关键的阈值:SKIP_PAGES_THRESHOLD = 32

什么意思? 如果一段可跳过页面的连续区间太短,PostgreSQL 可能宁可继续顺序扫描,也不选择跳页。 原因不是偷懒,而是工程理性:

  • 小范围跳页未必比顺序扫更划算
  • 还可能破坏内核 readahead
  • 对整体吞吐未必有利

也就是说, “理论上能跳过”不代表“实现上就一定跳过”

第二种情况:eager freeze

即使页面已经 all-visible,如果它还不是 all-frozen,正常 VACUUM 仍可能去扫它。 为什么?

因为 PostgreSQL 会做一件事:提前冻结。 它希望把未来 aggressive VACUUM 必须承担的冻结债务,尽量在平时就消化掉。

所以,正常 VACUUM 访问 all-visible but not all-frozen 页面,并不反常,反而是为了把未来的大成本打散到今天的小成本里。

这次优化到底优化了什么?

答案很精准:减少“明知没有 pruning/freezing 收益,却仍然进入 heap_page_prune_and_freeze() 流程”的无效开销。

这不是改 VACUUM 大框架。 不是改 visibility map 语义。 不是改冻结策略。 不是改查询优化器。

它只是识别出一个很典型的问题:

有些页面虽然最终什么都不用做,但流程还是跑进去了。

于是现在直接在入口前加一道判断:

  • 已经 all-frozen 的页,没必要再折腾
  • 已经 all-visible 且本轮根本不会 freeze 的页,也没必要再折腾
  • 只有一种情况不能信这个捷径:DISABLE_PAGE_SKIPPING

这也很好理解。 DISABLE_PAGE_SKIPPING 本来就是在怀疑页面跳过逻辑或可见性信息不该被信任时才用的。 既然你都说“不要跳页了”,那当然也不能再基于这些状态做早退。

哪些场景最受益?哪些场景别高估?

最受益的场景

这类优化最适合下面这些对象:

  • 历史数据分区
  • 更新删除很少,但 autovacuum 仍会持续巡检的大表
  • 已经形成大量 all-visible / all-frozen 页的数据集
  • 冷数据比例高、页面状态长期稳定的业务表

这些表的共同特征是: 页很“干净”,但维护系统仍可能偶尔误入处理路径。

过去的情况是:

  • 扫到了
  • 进函数了
  • 判断一圈
  • 最后发现没活干

现在则是:

  • 早点认清现实
  • 直接返回
  • 不再为空页流程交税

别高估的场景

如果你的表是下面这种风格,这次优化就不该被吹成“性能革命”:

  • 高频 UPDATE/DELETE
  • 页面上经常有 dead tuple
  • HOT 链活跃
  • 冻结压力持续存在
  • autovacuum 本来就一直有实活要做

在这些场景里,页面确实有 pruning/freezing 工作。 那 fast path 自然不会替你省下太多。

换句话说,这次改动的收益高度依赖前提条件:

  • 如果页面大多已经稳定、干净、可见性图健康,收益会积累
  • 如果页面本来就充满版本 churn,这个收益就会迅速收敛

前提一变,结论就得变。 这才是严肃讨论数据库优化该有的逻辑。

DBA 和开发者,各该看懂什么?

对 DBA

不要再把 autovacuum 只当成“不得不做的清洁工”。 它本质上是数据库的性能资产管理系统

visibility map 越健康,all-visible / all-frozen 页越多,后续:

  • 能跳过的页越多
  • 能早退的路径越多
  • aggressive VACUUM 的压力越容易被平摊
  • 系统长期维护成本越低

这次 commit 释放的信号很明确: PostgreSQL 越来越在意维护路径上的“无效动作”了。

对开发者

你写出来的不只是 SQL,也是数据库的维护成本曲线。

如果你的业务模型和访问模式总是在制造:

  • 短命版本链
  • 高频无效更新
  • 长期半新半旧的页面状态

那你不是只在拖慢查询, 你是在给 VACUUM、冻结、膨胀治理持续加税。

开发者常见的错觉是: “后台维护是 DBA 的事。”

不,后台维护从来都是应用行为的镜子。

这类 commit,为什么比“重大新特性”更值得敬畏?

因为真正决定数据库能否长期稳定跑下去的,往往不是某个 headline feature, 而是这种看起来不轰动、但持续压缩复杂性成本的工程改进。

PostgreSQL 社区这次的处理非常典型:

  • 不推翻原有机制
  • 不制造新复杂度
  • 不写巨型重构 PR
  • 只是在现有 VACUUM / pruning / freezing / visibility map 框架里
  • 精确识别一个“明知没有收益的动作”
  • 然后把它切掉

这才是成熟数据库内核最值钱的能力。 不是“做更多”,而是知道哪些事根本不该做

结尾

如果把数据库系统比作一家公司,很多系统不是死于一次重大事故, 而是死于每天都在发生、却没人盯上的小浪费。

这个 PostgreSQL commit 的价值,就在于它继续把这样一笔“隐形税”做薄了。 它不会让你一夜之间 benchmark 翻倍, 但它会让数据库在真实生产环境里,少一点无意义消耗,多一点长期稳定性。

你怎么看? 你在线上更担心 PostgreSQL 的前台 SQL 性能,还是后台 VACUUM / 冻结 / 膨胀 这些“慢性成本”?欢迎留言聊聊。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-04-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 digoal德哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • PG 19 Vacuum 又提速了
  • 为什么这件事重要?
  • 先把两个概念说清楚:all-visible 不等于 all-frozen
    • all-visible 是什么?
    • all-frozen 又是什么?
  • 关键误区:可跳过,不等于永远不会访问
    • 第一种情况:SKIP_PAGES_THRESHOLD
    • 第二种情况:eager freeze
  • 这次优化到底优化了什么?
  • 哪些场景最受益?哪些场景别高估?
    • 最受益的场景
    • 别高估的场景
  • DBA 和开发者,各该看懂什么?
    • 对 DBA
    • 对开发者
  • 这类 commit,为什么比“重大新特性”更值得敬畏?
  • 结尾
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档