VACUUM
VACUUM — 垃圾收集并按需分析数据库
大纲
VACUUM [ ( { FULL | FREEZE | VERBOSE | ANALYZE } [, ...] ) ] [ table_name [ (column_name [, ...] ) ] ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ table_name ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table_name [ (column_name [, ...] ) ] ]描述
VACUUM回收死元组占用的存储空间。在正常的
PostgreSQL运行中,被删除或因更新而过时的元组并不会从其表中物理移除;它们会一直保留,直到执行
VACUUM。因此有必要定期执行
VACUUM,尤其是对频繁更新的表。
不带参数时,VACUUM会处理当前数据库中当前用户有权清理的每个表。带参数时,VACUUM则只处理该表。
VACUUM ANALYZE会对每个选定表先执行
VACUUM,再执行ANALYZE。这种便捷的组合形式很适合例行维护脚本使用。关于其处理细节,参见ANALYZE。
普通的VACUUM(不带FULL)只是回收空间并使其可被重用。这种形式的命令可以与表的正常读写并行运行,因为它不会获得独占锁。不过,在大多数情况下,额外空间不会返还给操作系统;它只是保留在同一张表内供再次使用。VACUUM FULL会把表的全部内容重写到一个没有额外空闲空间的新磁盘文件中,从而让未使用的空间能够返还给操作系统。这种形式要慢得多,并且在处理每个表时都需要独占锁。
当选项列表用圆括号括起来时,选项可以按任意顺序书写。如果不加圆括号,则必须严格按照上面所示的顺序指定选项。带圆括号的语法是在PostgreSQL 9.0 中加入的;不带圆括号的语法已被弃用。
参数
FULL选择“完全”清理,它可以回收更多空间,但耗时更长,并且会独占锁定该表。这种方法还需要额外的磁盘空间,因为它会写出该表的一个新副本,并且在操作完成之前不会释放旧副本。通常,只有当需要从表内回收大量空间时才应使用这种方法。
FREEZE选择激进的元组“冻结”。指定
FREEZE等价于执行一个将vacuum_freeze_min_age参数设为零的VACUUM。VERBOSE为每个表输出详细的清理活动报告。
ANALYZE更新规划器用来确定查询最高效执行方式的统计信息。
table_name要清理的特定表的名称(可选地带模式限定)。默认为当前数据库中的所有表。
column_name要分析的特定列名。默认会分析所有列。如果指定了列列表,则隐含指定
ANALYZE。
输出
指定VERBOSE时,VACUUM会输出进度消息,指示当前正在处理哪个表,同时还会打印这些表的各种统计信息。
注解
要清理一个表,通常调用者必须是该表的拥有者或超级用户。不过,数据库拥有者可以清理其数据库中的所有表,但共享系统目录除外。(对共享系统目录的这一限制意味着,真正意义上的全数据库
VACUUM 只能由超级用户执行。)VACUUM 会跳过调用用户无权清理的任何表。
VACUUM不能在一个事务块内被执行。
对于带有GIN索引的表,VACUUM(任何形式)还会通过把待处理的索引项移动到主
GIN索引结构中的适当位置,来完成所有挂起的索引插入。详见第 55.3.1 节。
我们建议对活跃的生产数据库频繁执行清理(至少每晚一次),以移除死行。在添加或删除大量行之后,对受影响的表执行VACUUM ANALYZE命令可能是个好主意。这会用所有近期变更的结果更新系统目录,使PostgreSQL查询规划器在规划查询时能够做出更好的选择。
FULL选项不建议在日常场景中使用,但在某些特殊情况下可能很有用。例如,当你删除或更新了表中的绝大多数行,并希望该表在物理上收缩以占用更少磁盘空间、让表扫描更快时,这个选项就比较合适。VACUUM FULL通常会比普通
VACUUM更大幅度地收缩表。
VACUUM会显著增加 I/O 流量,这可能导致其他活动会话性能变差。因此,有时建议使用基于代价的清理延迟特性。详见第 18.4.4 节。
PostgreSQL提供了一个“自动清理(autovacuum)”机制,可以自动执行常规清理维护。有关自动与手动清理的更多信息,参见第 23.1 节。
示例
清理单个表onek,对其进行分析以供优化器使用,并打印详细的清理活动报告:
VACUUM (VERBOSE, ANALYZE) onek;
兼容性
在SQL标准中没有VACUUM语句。