做 DBA 的都知道,定期维护大表是件头疼事:
PostgreSQL 新增 REPACK (CONCURRENTLY) 选项,核心思路:把锁持有时间压缩到最短。
它是怎么做到的?三步走:
阶段1:数据复制(可读写)
↓
阶段2:捕获变更(可读写)
↓
阶段3:最终切换(短暂锁表)
方式 | 阻塞时间 | 表可读写 |
|---|---|---|
传统 REPACK | 30+ 分钟 | 全程不可 |
REPACK CONCURRENTLY | 约 20 秒 | 大部分时间可 |
-- 对 200GB 订单表执行并发维护
REPACK (CONCURRENTLY) orders;
-- 查看进度
SELECT * FROM pg_stat_progress_repack;
预期效果:
并发 repack 需要追踪数据变更,所以表必须满足:
-- 检查是否有 replica identity
SELECT relname, relreplident FROM pg_class
WHERE relkind = 'r';
-- 如果是 NOTHING,需要先设置
ALTER TABLE my_table REPLICA IDENTITY USING INDEX my_pkey;
不支持的场景:
max_replication_slots 够用以前:维护大表 = 通知业务停机 = 半夜干活。
现在:REPACK (CONCURRENTLY),业务基本不受影响,DBA 白天也能干活了。
建议:对所有 10GB 以上的大表,优先尝试 CONCURRENTLY 模式。维护窗口不再需要"惊险一跃"。