编程 PostgreSQL 19 的 REPACK:一条命令顶掉 VACUUM FULL、CLUSTER 和 pg_repack

2026-11-14 21:02:39

PostgreSQL 19 的 REPACK:一条命令顶掉 VACUUM FULL、CLUSTER 和 pg_repack

PostgreSQL 19 的 GA 计划是 2026-11-19,RC1 在 2026-10-15。这个版本里对日常运维影响最大的一项,是新增的 REPACK 命令:它替代 VACUUM FULL 与 CLUSTER,旧命令保留以兼容既有脚本。更关键的是 REPACK (CONCURRENTLY) 不拿 ACCESS EXCLUSIVE 锁,重建期间读写照常进行。

它解决的是什么问题

表膨胀之后的整理,过去有三条路:VACUUM FULL、CLUSTER、第三方 pg_repack。前两个都要排他锁,业务得停或得挑窗口;第三个要装扩展、建触发器或走逻辑复制通道。PG19 把这三件事合并进一个 in-core 命令,CONCURRENTLY 形式不再阻塞读写。

怎么工作

REPACK (CONCURRENTLY) 的重建期与切换期是分开的:

  • 重建阶段,并发读写继续落在原 heap 上,新表按原表结构重写一份;
  • 期间通过复制 slot 收集原表上的变更,把增量同步到新表;
  • 最后做一次切换,把表指向新 heap。

复制 slot 的池子由新增的服务变量 max_repack_replication_slots 控制。也就是说,并发重建不是免费午餐,它消耗的是复制 slot 这类实例级资源,同时进行的并发 REPACK 数量直接受这个参数约束。实例上已有逻辑复制、物理复制或备份正在占用 slot 时,这个参数的余量要先算清楚。

代价

三笔账要提前算:

  1. WAL 膨胀。重建本身就要写大量 WAL,追加的增量同步还会再放大一轮。WAL 归档、备库回放、跨区传输的带宽都会被这条命令拉满。
  2. slot 池。REPACK (CONCURRENTLY) 依赖复制 slot,max_repack_replication_slots 给小了会失败或排队,给大了会把 slot 资源从逻辑复制那边挤走。
  3. 磁盘双份。切换前新旧两份数据同时存在,表有多大,峰值就要多预留接近一份的空间,索引一并计入。

所以大表上的 REPACK (CONCURRENTLY) 是「用 WAL、slot 和磁盘换业务无感」,而不是零成本操作。

命令示例

-- 重建表(对应 VACUUM FULL 的整理目的)
REPACK orders;

-- 并发重建,不阻塞读写;需要可用的 repack 复制 slot
REPACK (CONCURRENTLY) orders;

-- 按索引重排,对应 CLUSTER 的用法
REPACK orders USING orders_created_at_idx;

slot 池按实例规模设置,例如:

max_repack_replication_slots = 4

这个值要与实例上同时运行的并发 REPACK 数量、以及已有的复制/备份 slot 需求一起决定,不要照抄。

上线前检查

  • 磁盘:目标表数据 + 索引的近似大小,剩余空间要能容纳新旧两份,并留出 WAL 的余量;
  • slot:确认 max_repack_replication_slots 有余量,且不会挤掉逻辑复制与备份使用的 slot;
  • WAL 链路:归档目录、备库延迟阈值、跨区带宽能否承受短时激增;
  • 锁与长事务:虽然不拿 ACCESS EXCLUSIVE,切换阶段仍要能及时拿到所需锁,先清掉长事务再执行;
  • 灰度:先在低峰期用小表跑一次,观察 WAL 生成速率与复制延迟,再上大表。

PG19 其他相关变更

同一版本还有几项与运维路线相关:

  • pg_plan_advice 扩展可生成 plan advice 字符串,通过 EXPLAIN (PLAN_ADVICE '...') 一次性注入;pg_stash_advice 按 query id 自动应用;
  • autovacuum 支持并行,参数为 autovacuum_max_parallel_workers 与每表的 autovacuum_parallel_workers,新增 pg_stat_autovacuum_scores 视图和 autovacuum_*_score_weight 系列参数;
  • 新增 pg_stat_recovery、pg_stat_lock 视图;
  • 逻辑复制支持序列值(ALL SEQUENCES、REFRESH SEQUENCES);
  • wal_level=replica 时可自动启用逻辑复制,并新增 effective_wal_level;
  • WAIT FOR LSN 支持备库上的 read-your-writes;
  • io_method=worker 时按 io_min_workers / io_max_workers 自动扩缩;
  • JIT 默认关闭,default_toast_compression 默认改为 lz4;
  • 移除 RADIUS。

RC 期间修掉的问题里,与本文直接相关的是 REPACK 的崩溃、无效索引与物化视图行为、权限与报错;另有 WAIT FOR 的死锁与隔离级别报错,以及 parallel autovacuum 的多项修复。计划在生产上使用 REPACK (CONCURRENTLY) 的实例,建议直接以 GA 版本或包含这些修复的 RC 为基线。

复制全文 生成海报 PostgreSQL 运维 数据库

推荐文章

程序员茄子在线接单