PostgreSQL码农集散地

PG 宣布 vacuum full成为历史, REPACK 进入主干代码

本期播客

PG vacuum full成为历史, REPACK 进入主干代码

管理的本质,不是记住更多命令,而是用更清晰的抽象解决核心问题。

凌晨 2 点,你收到磁盘空间告警。登录数据库,发现一张 500GB 的表,实际有效数据只有 300GB,200GB 是 MVCC 留下的“幽灵”碎片。你需要在业务低峰期执行 VACUUM FULL 来回收空间,但这条命令会锁表数小时。业务方怒吼:“绝对不能停!”你陷入两难:空间马上爆了,表又不能锁。最后,你只能冒险使用第三方工具 pg_repack,祈祷它不要在关键时刻出 bug。

这种噩梦,在 PostgreSQL 19 中,有望随着 REPACK 命令的引入而成为历史。

2026 年 3 月,Álvaro Herrera 提交的 ac58465e 补丁,正式在 PostgreSQL 中引入了 REPACK 命令。它不是一个简单的语法糖,而是一场酝酿多年的存储维护革命。

第一性原理:为什么我们需要“重新打包”表?

让我们回到 PostgreSQL 的存储本质。PostgreSQL 通过 MVCC(多版本并发控制) 实现 ACID,其核心机制是:更新或删除行时,并不直接修改原数据,而是标记旧行“死亡”,并写入新行。

这带来了一个必然结果: 表会随着时间推移产生“空洞”(碎片) 。原本紧凑的数据页,渐渐变得稀疏,导致:

  1. 空间膨胀:100GB 的业务数据可能占用 200GB 磁盘。
  2. 性能下降:顺序扫描需要读取更多无用的页,缓存命中率下降。

要彻底解决这个问题,唯一的办法是重写整个表,将有效数据紧凑地写入新的存储文件,然后扔掉旧文件。这个过程,就是“重新打包”(Repack)。

在 REPACK 命令出现前,我们有两条路:

  • VACUUM FULL:重写表并回收空间,但持有排他锁,期间表不可读写。
  • CLUSTER:根据索引顺序重写表,同样持有排他锁,且“cluster”一词在 IT 领域严重过载(数据库集群?),极易混淆。

这两条路的共同痛点是:无法在线执行。对于 24/7 的业务,这意味着你必须依赖外部工具(如 pg_repack、pg_squeeze)。

破局者:REPACK——统一且面向未来的抽象

REPACK 的核心价值,在于它从第一性原理出发,重新审视了表重写这一操作的本质。

它吸收了 VACUUM FULL 和 CLUSTER 的功能,但提供了更清晰的抽象:

你的需求
旧时代写法
REPACK 新写法
仅回收空间,不关心顺序
VACUUM FULL tab;REPACK tab;
按特定索引顺序重写
CLUSTER tab USING idx;REPACK tab USING INDEX idx;
按表预设的聚簇索引重写
CLUSTER tab;REPACK tab USING INDEX;
对所有已设置聚簇索引的表重写
CLUSTER;REPACK USING INDEX;

这不仅是一次语法统一,更是一次概念降噪。 从此,DBA 不再需要向新同事解释“为什么 VACUUM FULL 和普通 VACUUM 做的事情完全不同”,也不需要面对“cluster”一词的语义混淆。

更宏伟的蓝图:CONCURRENTLY 模式的曙光

补丁提交者 Álvaro Herrera 在邮件列表中透露了更深的意图:这个重构是为了给未来的“并发模式”(CONCURRENTLY)铺路。

这正是第一性原理思维的延伸。表重写的本质是“构建新副本并切换”,但难点在于切换期间如何处理并发修改。第三方工具 pg_squeeze 已经证明,通过逻辑解码捕获增量变化,可以实现在线、低锁的表重写。

REPACK 命令的引入,为这种并发模式提供了一个干净的语法入口和代码基础。未来,我们可能只需要:

-- 未来语法(构想)  
REPACK CONCURRENTLY tab;  

这条命令将:

  1. 创建一个新表的副本。
  2. 利用逻辑复制捕获原表上的增量修改。
  3. 在流量极低(甚至为零)的瞬间完成切换,业务几乎无感知。

权威数据和案例:为什么这能改变游戏规则?

案例:一个 2TB 电商订单表的教训

某电商公司,订单表 orders 因频繁的更新状态和删除过期数据,年碎片率达 40%。他们每季度需要执行一次 VACUUM FULL,耗时 6 小时,期间订单写入完全阻塞。为了这 6 小时,他们必须提前公告停机维护,每次损失数百万 GMV。

如果使用未来的 REPACK CONCURRENTLY:

  • 锁表时间:从 6 小时 降至 < 1 秒(仅元数据切换)。
  • 业务影响:从 完全不可用 降至 几乎为零。
  • 运维成本:无需协调停机窗口,DBA 可随时执行。

权威数据:碎片整理的性能收益

根据 Cybertec(Antonin Houska 所在公司)的 benchmark,一个碎片率达 30% 的表:

  • 顺序扫描性能:下降 35% - 50% 。
  • 索引扫描性能:因索引与表的关联性降低,可能下降 20% - 30% 。
  • 重写后:扫描性能恢复如初,缓存利用率提升。

第三方工具的局限性

目前广泛使用的 pg_repack 和 pg_squeeze 是英雄般的作品,但它们存在固有缺陷:

  1. 安装复杂:需要安装额外扩展和二进制文件。
  2. 特权要求高:通常需要超级用户权限。
  3. 风险自负:作为外部工具,与核心备份、监控工具的集成度低,出现问题社区支持有限。
  4. 维护滞后:每次 PostgreSQL 大版本升级,都需要等待工具适配。

REPACK 的内核化,意味着这些能力将成为数据库的“一等公民”,由全球最顶尖的 PG 开发者共同维护,与备份、复制、监控体系无缝集成。

第一性原理的边界:什么时候 REPACK 失效?

任何抽象都有前提。REPACK 的核心前提是: 表可以被重写且业务可接受短暂锁表(当前版本)或最终一致(未来并发版本) 。当这些前提崩塌时,我们需要回归本质。

崩塌场景 1:绝对零停机

即使未来的 CONCURRENTLY 模式,也可能存在毫秒级的切换窗口。对于需要“五个九”可用性、且无法接受任何连接闪断的极核心系统(如证券交易流水),这可能仍不可接受。

应对策略:此类系统通常采用“append-only”模式,根本不允许更新和删除,从源头消除了碎片。或者使用 PARTITION 结合 DROP PARTITION 来零代价回收空间。

崩塌场景 2:磁盘空间严重不足

REPACK(以及任何表重写操作)都需要额外的磁盘空间来存放新版本的副本。如果磁盘剩余空间小于目标表大小,操作将无法启动。

应对策略:

  • 紧急扩容磁盘(云环境可以秒扩)。
  • 采用更激进的方式:pg_dump 导出再导入(同样需要空间)。
  • 如果碎片率极高,可以考虑在从库上执行重写后切换,但这涉及更复杂的容灾架构。

崩塌场景 3:超大表的超长重写时间

一张 10TB 的表,即使在线重写,也可能需要数天。长时间的逻辑解码可能堆积 WAL,导致主库磁盘爆满。

应对策略:此类“超大表”通常需要数据生命周期管理(归档、分区)。REPACK 不是解决所有存储问题的银弹,良好的数据架构才是根本。

迁移指南:DBA 现在该做什么?

1. 学习新语法,更新 SOP

立即更新你们的运维手册。将所有的 VACUUM FULL 和 CLUSTER 命令替换为等价的 REPACK 命令。这不仅是为了兼容 PG19,更是为了统一团队的认知。

2. 测试新命令,评估收益

在测试环境,对一个碎片率较高的表执行:

-- 测试 REPACK 的锁行为和耗时  
BEGIN;  
LOCKTABLE your_table INACCESS EXCLUSIVE MODE; -- 模拟锁  
REPACK your_table;  
ROLLBACK;  

观察执行时间,并与 VACUUM FULL 对比。理论上应该相近,但这是为未来做基准测试。

3. 关注并发模式的进展

密切跟踪 PostgreSQL 19 后续小版本或 PG20 的开发动态。一旦 REPACK CONCURRENTLY 稳定可用,立即规划将其纳入你的零停机维护工具箱。

4. 重新评估外部工具

如果你目前依赖 pg_repack,可以开始评估迁移到内核 REPACK 的计划。优先在非核心系统上试用,验证其稳定性和性能。

未来展望:从命令到生态

REPACK 的引入,可能开启 PostgreSQL 存储维护的新纪元:

  • repackdb 客户端工具:类似 vacuumdb,允许并行、批量地重写多个数据库的表。
  • 智能自动化:结合 pg_stat_user_tables 中的 n_dead_tup 和 n_live_tup,未来或许能实现“自动碎片整理”,在碎片率达到阈值时自动触发低优先级、并发的 REPACK。
  • 与分区表深度集成:对单个过大的分区进行在线重写,而主表完全不受影响。

结语

PostgreSQL 19 的 REPACK 命令,不是一次激进的创新,而是一次必然的回归。它回归到表重写操作的本质,用更清晰的抽象统一了混乱的过去,并为优雅的未来——在线并发重写——铺平了道路。

对于 DBA 而言,这意味着告别凌晨的锁表噩梦,告别对第三方工具的提心吊胆,将时间和精力投入到更有价值的架构设计中去。

从今天起,忘掉 VACUUM FULL 和 CLUSTER 的纠缠,拥抱 REPACK 的清晰与力量。