PostgreSQL Vacuum 内部机制详解
1. VACUUM 操作概述
VACUUM 操作可使表重复利用已死亡元组的存储空间,供后续事务使用。但在每次插入、更新或删除操作时显式运行 VACUUM 命令并不可取,因为 VACUUM 是一个相当繁重的过程,它会扫描表中的所有元组,逐渐增加 I/O 利用率。同时,完全停止对任何表的 VACUUM 操作也不可行,这会导致磁盘上的死亡元组增多,从而造成磁盘利用率低下。
建议定期运行 VACUUM 过程,例如每天或每周一次,可以通过在 crontab 中调度命令或使用 pgBucket 来实现。从 PostgreSQL 8.1 开始,autovacuum 后台工作进程默认开启,它会在后台自动运行 VACUUM 操作,清理数据库中的死亡元组存储。
2. VACUUM 工作原理
当在任何表上执行 VACUUM 命令时,它会请求 postgres 实例发送当前正在运行的所有 SQL 查询列表。收到该列表后,VACUUM 进程会识别那些对正在运行的 SQL 查询不可见的死亡元组。然后,它会使用配置的 maintenance_work_mem 内存区域,将关系加载到内存中以识别死亡元组。一旦识别出所有死亡元组信息,它将为该关系生成一个 FSM(Free Space Map)文件,该文件将用于后续事务重复利用死亡元组的磁盘存储空间。
VACUUM 进程的另一项职责是通过验证 pg_clog 和 pg_subtrans 来更新表中每一行的事务状态。在 PostgreSQL 中,每行头部包含 xmin 和 xmax 值,这些值通过参考 pg_clog 中的状态位与事务状态(如进行中、已提交或已中止)相关联。