PostgreSQL 19 重磅更新:200GB 大表维护,业务“零中断”!
PostgreSQL 19 重磅更新:200GB 大表维护,业务竟然零中断!
痛点:传统 REPACK 的致命问题
做 DBA 的都知道,定期维护大表是件头疼事:
传统 REPACK/CLUSTER 需要 全程锁表 200GB 的表,复制可能需要 30 分钟 这 30 分钟内,业务表完全不可读写 对 7x24 系统来说,这是灾难
重大突破:REPACK CONCURRENTLY 来了
PostgreSQL 新增 REPACK (CONCURRENTLY) 选项,核心思路:把锁持有时间压缩到最短。
它是怎么做到的?三步走:
阶段1:数据复制(可读写)
↓
阶段2:捕获变更(可读写)
↓
阶段3:最终切换(短暂锁表)
原理揭秘
复制阶段:用 MVCC 快照复制当前数据,此时表完全可读写 变更捕获:启动后台 worker,用逻辑解码持续捕获业务变更(INSERT/UPDATE/DELETE) 最终切换:只在这个极短窗口需要锁
效果对比
实战案例
-- 对 200GB 订单表执行并发维护
REPACK (CONCURRENTLY) orders;-- 查看进度
SELECT * FROM pg_stat_progress_repack;
预期效果:
数据复制阶段:约 25 分钟,业务正常 变更捕获阶段:约 2-5 分钟,业务正常 最终切换阶段:约 20 秒,有短暂阻塞
重要前提:必须有主键或 REPLICA IDENTITY
并发 repack 需要追踪数据变更,所以表必须满足:
-- 检查是否有 replica identity
SELECT relname, relreplident FROM pg_class
WHERE relkind = 'r';-- 如果是 NOTHING,需要先设置
ALTERTABLE my_table REPLICA IDENTITYUSINGINDEX my_pkey;
不支持的场景:
分区表(需对单个分区执行) UNLOGGED / TEMP 表 没有主键也没有 REPLICA IDENTITY 的表
注意事项
需要 replication slot:记得提前确认 max_replication_slots够用全局单实例:同一时间只能有一个 REPACK CONCURRENTLY 在运行 业务低峰期执行:最终切换阶段仍需锁表,虽然很短,但建议避开高峰 变更量控制:如果维护期间业务变更太多,最终切换前的回放时间会变长
一句话总结
以前:维护大表 = 通知业务停机 = 半夜干活。
现在:REPACK (CONCURRENTLY),业务基本不受影响,DBA 白天也能干活了。
建议:对所有 10GB 以上的大表,优先尝试 CONCURRENTLY 模式。维护窗口不再需要"惊险一跃"。