PostgreSQL 如何解决膨胀问题?
PostgreSQL 如何解决膨胀问题?
1. VACUUM
PostgreSQL 内置命令,有两种模式:
VACUUM(普通)- 回收表中已删除或过期的元组(dead tuples)的空间。
- 空间一般不会释放给操作系统,而是留在表文件中供后续插入/更新复用。
- 速度快,不会锁表(仅短暂锁元数据)。
VACUUM FULL- 会新建一个干净的表文件,把有效数据重写到新文件中,释放磁盘空间给 OS。
- 会持有表的排它锁(exclusive lock),阻塞所有读写。
- 适合空间膨胀特别严重的场景,但会中断业务。
总结:
- 优点:Postgres 自带,简单直接。
- 缺点:普通 VACUUM 不释放磁盘;FULL 会长时间锁表。
2. pg_repack
pg_repack 是一个 在线重建表和索引 的扩展工具。
- 核心思路:在后台新建一个无膨胀的新表/索引,通过触发器捕捉并同步变更,最后原子替换。
- 能释放磁盘空间,而且全程几乎不阻塞读写(最终切换时会有极短锁)。
- 还可以重建索引以减少索引膨胀。
- 适合在生产环境进行空间回收和重建,无需停机。
总结:
- 优点:释放空间 + 不长时间阻塞业务。
- 缺点:需要安装扩展,有一定系统开销;对于极大表会产生额外的 I/O。
3. pg_squeeze
pg_squeeze是另一个 在线去膨胀 工具,但和 pg_repack 有些区别:
- 利用逻辑解码(logical decoding)在后台创建无膨胀的新表,并复制原表数据,同时捕捉 WAL 中的增量变更。
- 支持自动化去膨胀(可定时运行,不需要手工触发)。
- 对大表更友好,减少一次性重写的压力。
- 相比 pg_repack,它的目标更偏自动维护,而不是一次性的手动空间回收。
总结:
- 优点:可自动化、在线运行、减少维护成本。
- 缺点:需要开启
wal_level = logical,对 WAL 有额外压力;安装和配置比 pg_repack 复杂。
对比表
| 工具 | 是否在线 | 是否释放 OS 空间 | 是否锁表 | 使用场景 |
|---|---|---|---|---|
| VACUUM | 是 | 否(普通) | 否 | 日常维护,防止膨胀 |
| VACUUM FULL | 否 | 是 | 是(长时间) | 紧急空间回收 |
| pg_repack | 是 | 是 | 仅切换时极短 | 手动在线去膨胀 / 重建索引 |
| pg_squeeze | 是 | 是 | 仅切换时极短 | 自动化去膨胀,大表长期维护 |
💡 经验建议
- 日常:
VACUUM+ANALYZE(自动/定时) - 空间膨胀严重但可停机:
VACUUM FULL - 空间膨胀严重且业务不能停:
pg_repack - 希望长期自动化、平滑去膨胀:
pg_squeeze
- Title: PostgreSQL 如何解决膨胀问题?
- Author: Hao Feng
- Created at : 2025-08-14 23:38:28
- Updated at : 2025-08-14 09:22:14
- Link: https://matt23-star.github.io/2025/08/PostgreSQL-解决膨胀问题/
- License: This work is licensed under CC BY-NC-SA 4.0.
Comments