PostgreSQL中执行Delete操作删除数据时,数据库并不会直接把对应的磁盘空间返还给操作系统,而是将这些空间标记为可复用状态,长期积累就会形成磁盘碎片,既浪费存储空间,也可能影响后续查询的性能。VACUUM是PostgreSQL内置的用于清理这些碎片、回收存储空间的核心操作。

Delete后产生磁盘碎片的原因
PostgreSQL采用多版本并发控制(MVCC)机制,当执行Delete操作时,被删除的行并不会立即从磁盘中移除,只是被标记为已删除状态。这些被标记的空间只有在后续的VACUUM操作处理后,才会被整理并标记为可分配给新的数据行使用,否则就会一直以碎片的形式存在。
VACUUM操作的基本原理
VACUUM操作主要完成两个核心工作:一是扫描表中的所有页面,清理被标记为删除的无效行版本,减少表的体积;二是更新表的统计信息,帮助查询规划器生成更优的执行计划。普通的VACUUM操作不会锁表,不会阻塞正常的读写操作,适合日常维护使用。
不同VACUUM模式的使用方法
普通VACUUM
普通VACUUM仅清理无效行、更新统计信息,不会将回收的空间返还给操作系统,只是让这些空间可以被表自身后续复用。语法如下:
-- 清理指定表的空间碎片,更新统计信息 VACUUM 表名; -- 清理整个数据库所有表的碎片 VACUUM;
VACUUM FULL
VACUUM FULL会重写整个表,将有效的数据行重新整理到新的磁盘空间中,然后把旧的磁盘空间全部返还给操作系统,清理碎片的效果更彻底,但执行过程中会对表加排他锁,阻塞所有读写操作,适合在业务低峰期使用。语法如下:
-- 彻底清理指定表的空间,返还空间给操作系统 VACUUM FULL 表名; -- 彻底清理整个数据库所有表的空间 VACUUM FULL;
VACUUM ANALYZE
VACUUM ANALYZE在清理碎片的同时,会强制更新表的统计信息,避免清理后统计信息不准确导致查询计划偏差。语法如下:
-- 清理碎片并更新统计信息 VACUUM ANALYZE 表名;
操作注意事项
- 普通VACUUM可以在业务运行期间执行,对业务影响很小,建议定期执行维护。
- VACUUM FULL会锁表,执行前务必确认业务处于低峰期,避免影响正常服务。
- 如果表的数据量非常大,VACUUM FULL的执行时间会很长,要提前做好时间规划。
- 可以通过设置autovacuum参数让PostgreSQL自动执行VACUUM操作,减少手动维护的成本。
相关参数配置建议
PostgreSQL的autovacuum功能默认是开启的,相关核心参数可以在postgresql.conf中调整:
| 参数名 | 说明 | 建议值 |
|---|---|---|
| autovacuum | 是否开启自动VACUUM功能 | on |
| autovacuum_vacuum_threshold | 触发自动VACUUM的最小更新/删除行数 | 50 |
| autovacuum_analyze_threshold | 触发自动ANALYZE的最小更新/删除行数 | 50 |
操作示例
假设我们有一个名为user_info的用户表,执行了大量Delete操作后需要清理碎片,操作步骤如下:
首先查看当前表的磁盘占用情况:
-- 查看表的大小,包含索引
SELECT pg_size_pretty(pg_total_relation_size('user_info'));
然后执行普通VACUUM清理碎片:
VACUUM ANALYZE user_info;
如果需要彻底释放空间给操作系统,且业务处于低峰期,可以执行:
VACUUM FULL user_info;
执行完成后再次查看表的大小,就可以看到存储空间已经被有效回收。
PostgreSQLVACUUM磁盘碎片清理数据库优化修改时间:2026-07-10 07:27:29