VACUUM — 垃圾收集并按需分析数据库
VACUUM [ (option[, ...] ) ] [table_and_columns[, ...] ] VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [table_and_columns[, ...] ] 其中option为以下之一: FULL [boolean] FREEZE [boolean] VERBOSE [boolean] ANALYZE [boolean] DISABLE_PAGE_SKIPPING [boolean] SKIP_LOCKED [boolean] INDEX_CLEANUP [boolean] TRUNCATE [boolean] PARALLELinteger而table_and_columns为:table_name[ (column_name[, ...] ) ]
VACUUM回收死元组占用的存储空间。在正常的 PostgreSQL运行中,被删除或因更新而过时的元组 并不会从其表中物理移除;它们会一直保留,直到执行 VACUUM。因此有必要定期执行 VACUUM,尤其是对频繁更新的表。
如果没有给出table_and_columns 列表,VACUUM会处理当前数据库中当前用户有权清理的每个表和物化视图。 如果给出了列表,VACUUM则只处理其中列出的表。
VACUUM ANALYZE会对每个选定表先执行 VACUUM,再执行ANALYZE。 这种便捷的组合形式很适合例行维护脚本使用。关于其处理细节,参见 ANALYZE。
普通的VACUUM(不带FULL)只是回收空间并使其可被重用。 这种形式的命令可以与表的正常读写并行运行,因为它不会获得独占锁。 不过,在大多数情况下,额外空间不会返还给操作系统;它只是保留在同一张表内供再次使用。 它还允许利用多个 CPU 来处理索引,这项功能称为并行清理。 如需禁用该功能,可以使用PARALLEL选项并将并行工作者数指定为零。 VACUUM FULL会把表的全部内容重写到一个没有额外空闲空间的新磁盘文件中, 从而让未使用的空间能够返还给操作系统。这种形式要慢得多,并且在处理每个表时都需要 ACCESS EXCLUSIVE锁。
当选项列表用圆括号括起来时,选项可以按任意顺序书写。如果不加圆括号,则必须严格按照上面所示的顺序指定选项。带圆括号的语法是在PostgreSQL 9.0 中加入的;不带圆括号的语法已被弃用。
FULL选择“完全”清理,它可以回收更多空间,但耗时更长,并且会独占锁定该表。 这种方法还需要额外的磁盘空间,因为它会写出该表的一个新副本,并且在操作完成之前 不会释放旧副本。通常,只有当需要从表内回收大量空间时才应使用这种方法。
FREEZE选择激进的元组“冻结”。指定FREEZE 等价于执行一个将vacuum_freeze_min_age和 vacuum_freeze_table_age参数设为零的 VACUUM。在表被重写时总会执行激进冻结,因此指定了 FULL时,这个选项就是多余的。
VERBOSE为每个表输出详细的清理活动报告。
ANALYZE更新规划器用来确定查询最高效执行方式的统计信息。
DISABLE_PAGE_SKIPPING通常,VACUUM会根据可见性映射跳过某些页面。已知其中所有元组都已冻结的页面总是可以跳过, 而已知其中所有元组都对所有事务可见的页面,也可以跳过,除非正在执行激进清理。 此外,除非正在执行激进清理,为了避免等待其他会话结束对页面的使用,也可能会跳过某些页面。 此选项会禁用所有跳页行为,只应在怀疑可见性映射内容存在问题时使用;而这种情况通常只会在 硬件或软件问题导致数据库损坏时发生。
SKIP_LOCKED指定VACUUM在开始处理某个关系时,不要等待任何冲突锁被释放: 如果某个关系无法在无需等待的情况下立即获得锁,就跳过该关系。请注意,即使使用了此选项, VACUUM在打开该关系的索引时仍可能发生阻塞。此外, VACUUM ANALYZE在从分区、继承子表和某些类型的外部表获取样本行时, 仍然可能发生阻塞。还有,虽然VACUUM通常会处理指定分区表的全部分区, 但如果该分区表上存在冲突锁,此选项会导致VACUUM跳过所有分区。
INDEX_CLEANUP指定VACUUM应尝试移除指向死元组的索引项。这通常是期望的行为,也是默认行为,除非待清理表的vacuum_index_cleanup选项被设为 false。在需要让清理尽可能快地运行时,将此选项设为 false 可能会有用,例如为了避免临近的事务 ID 回卷(参见Section 24.1.5)。不过,如果不定期执行索引清理,性能可能会受到影响,因为随着表被修改,索引会积累死元组,而表本身也会积累在索引清理完成前无法移除的死行指针。对没有索引的表,此选项没有效果;如果使用了FULL选项,它也会被忽略。
TRUNCATE指定VACUUM应尝试截去表末尾的空页,使这些被截断页面占用的磁盘空间能够返还给操作系统。通常这是期望的行为,也是默认行为,除非待清理表的vacuum_truncate选项被设为 false。将此选项设为 false 有助于避免截断操作所需的表级ACCESS EXCLUSIVE锁。使用FULL选项时,此选项会被忽略。
PARALLEL并行执行VACUUM的索引清理和索引收尾清理阶段,使用integer个后台工作进程(每个清理阶段的细节参见 Table 27.37)。实际用于执行操作的工作进程数量,等于该关系上支持并行清理的索引数量, 如果指定了PARALLEL选项,则该数量受其中指定的工作进程数限制,并进一步受 max_parallel_maintenance_workers限制。只有当索引大小大于 min_parallel_index_scan_size时,该索引才能参与并行清理。 请注意,执行期间不保证一定会使用integer中指定的并行工作进程数。 一次清理可能使用少于指定数量的工作进程,甚至完全不使用工作进程。每个索引最多只能使用一个工作进程, 因此只有当表中至少有2个索引时才会启动并行工作进程。清理工作进程会在每个阶段开始前启动, 并在该阶段结束时退出。这些行为未来版本中可能会发生变化。此选项不能与FULL选项一起使用。
boolean指定打开还是关闭所选选项。你可以写入 TRUE、ON或1 来启用该选项,以及写入FALSE、 OFF或0来禁用它。 boolean值也可以省略, 此时假定为TRUE。
integer指定传递给所选选项的非负整数值。
table_name要清理的特定表或物化视图的名称(可选地带模式限定)。如果指定的表是分区表,则清理它的所有叶子分区。
column_name要分析的特定列名。默认会分析所有列。如果指定了列列表,则也必须指定ANALYZE。
指定VERBOSE时,VACUUM会输出进度消息, 指示当前正在处理哪个表,同时还会打印这些表的各种统计信息。
要清理一个表,通常调用者必须是该表的拥有者或超级用户。 不过,数据库拥有者可以清理其数据库中的所有表,但共享系统目录除外。 (对共享系统目录的这一限制意味着,真正意义上的全数据库 VACUUM 只能由超级用户执行。) VACUUM 会跳过调用用户无权清理的任何表。
VACUUM不能在一个事务块内被执行。
对于带有GIN索引的表,VACUUM(任何形式)还会通过把待处理的索引项移动到主 GIN索引结构中的适当位置,来完成所有挂起的索引插入。详见 Section 66.4.1。
我们建议对活跃的生产数据库频繁执行清理(至少每晚一次),以移除死行。在添加或删除大量行之后,对受影响的表执行VACUUM ANALYZE命令可能是个好主意。这会用所有近期变更的结果更新系统目录,使PostgreSQL查询规划器在规划查询时能够做出更好的选择。
FULL选项不建议在日常场景中使用,但在某些特殊情况下可能很有用。 例如,当你删除或更新了表中的绝大多数行,并希望该表在物理上收缩以占用更少磁盘空间、 让表扫描更快时,这个选项就比较合适。VACUUM FULL通常会比普通 VACUUM更大幅度地收缩表。
PARALLEL选项只用于清理。如果此选项与ANALYZE选项一起指定, 它不会影响ANALYZE。
VACUUM会显著增加 I/O 流量,这可能导致其他活动会话性能变差。 因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作者的睡眠时长 都与该工作者完成的工作量成比例。详见Section 19.4.4。
PostgreSQL提供了一个“自动清理(autovacuum)”机制,可以自动执行常规清理维护。有关自动与手动清理的更多信息,参见Section 24.1。
清理单个表onek,对其执行优化器分析,并打印详细的清理活动报告:
VACUUM (VERBOSE, ANALYZE) onek;
在SQL标准中没有VACUUM语句。