VACUUM — 清理垃圾并可选地分析一个数据库
VACUUM [ (option[, ...] ) ] [table_and_columns[, ...] ] whereoptioncan be one of: FULL [boolean] FREEZE [boolean] VERBOSE [boolean] ANALYZE [boolean] DISABLE_PAGE_SKIPPING [boolean] SKIP_LOCKED [boolean] INDEX_CLEANUP { AUTO | ON | OFF } PROCESS_MAIN [boolean] PROCESS_TOAST [boolean] TRUNCATE [boolean] PARALLELintegerSKIP_DATABASE_STATS [boolean] ONLY_DATABASE_STATS [boolean] BUFFER_USAGE_LIMITsizeandtable_and_columnsis: [ ONLY ]table_name[ * ] [ (column_name[, ...] ) ]
VACUUM 回收被死元组占用的存储空间。在 PostgreSQL 的正常运行中,被删除的元组或被更新废弃的元组并不会从其表中物理移除;它们会一直保留,直到完成一次 VACUUM。因此有必要定期执行 VACUUM,尤其是在频繁更新的表上。
如果没有 table_and_columns 列表,VACUUM 会处理当前数据库中当前用户有权清理的每一个表和物化视图。如果有列表,VACUUM 只处理那些表。
VACUUM ANALYZE 会对每个选定的表先执行一次 VACUUM,然后执行一次 ANALYZE。对于日常维护脚本来说,这是一种方便的组合形式。有关其处理的更多细节,请参见 ANALYZE。
普通 VACUUM(不带 FULL)只是回收空间并使其可供重用。这种形式的命令可以与表的正常读写并行进行,因为它不会获取排他锁。不过,多余的空间(在大多数情况下)不会返还给操作系统,只是保留在同一表内供重用。它还允许利用多个 CPU 来处理索引。这个特性被称为 并行清理(parallel vacuum)。要禁用该特性,可以使用 PARALLEL 选项并把并行工作者数指定为零。VACUUM FULL 会把表的全部内容重写到一个没有任何多余空间的新磁盘文件中,从而允许把未使用的空间返还给操作系统。这种形式要慢得多,并且在处理期间需要对每个表持有 ACCESS EXCLUSIVE 锁。
FULL选择 “完全”(full)清理,它可以回收更多空间,但耗时更长,并且会以排他方式锁住表。这种方法还需要额外的磁盘空间,因为它会写入表的一个新副本,并且直到操作完成后才释放旧副本。通常只有在需要从表内回收大量空间时才应该使用它。
FREEZE 选择对元组进行激进的 “冻结”。指定 FREEZE 相当于执行一次 VACUUM,并将其 vacuum_freeze_min_age 与 vacuum_freeze_table_age 参数设置为零。当表被重写时总是会执行激进冻结,因此在指定 FULL 时这个选项是多余的。
VERBOSE 为每个表以 INFO 级别打印详细的清理活动报告。
ANALYZE更新规划器用来确定执行查询最高效方式的统计信息。
DISABLE_PAGE_SKIPPING 通常,VACUUM 会根据可见性映射跳过一些页。已知所有元组都被冻结的页总是可以被跳过,已知所有元组对所有事务可见的页也可以被跳过,但执行激进清理时除外。此外,除非在执行激进清理,否则某些页可能会被跳过,以避免等待其他会话用完它们。这个选项会禁用所有跳页行为,仅应在可见性映射的内容可疑时使用,而这种情况只应在出现导致数据库损坏的硬件或软件问题时才会发生。
SKIP_LOCKED 指定 VACUUM 在开始处理一个关系时不应等待任何冲突的锁被释放:如果不能立即无等待地锁定某个关系,则跳过该关系。注意,即使使用这个选项,VACUUM 在打开关系的索引时仍然可能阻塞。此外,VACUUM ANALYZE 在从分区、表继承子表以及某些类型的外部表获取采样行时仍然可能阻塞。还有,虽然 VACUUM 通常会处理指定的分区表的所有分区,但如果分区表上存在冲突的锁,这个选项会导致 VACUUM 跳过所有分区。
INDEX_CLEANUP 通常,当表中的死元组非常少时,VACUUM 会跳过索引清理。发生这种情况时,处理该表所有索引的代价预计会远超过移除死索引元组带来的收益。这个选项可用于强制 VACUUM 在死元组数大于零时处理索引。默认值是 AUTO,它允许 VACUUM 在适当时跳过索引清理。如果 INDEX_CLEANUP 被设置为 ON,VACUUM 会保守地从索引中移除所有死元组。这可能有助于向后兼容 PostgreSQL 的早期版本,在那些版本中这是标准行为。
INDEX_CLEANUP 也可以被设置为 OFF,以强制 VACUUM 总是跳过索引清理,即使表中有很多死元组。当需要让 VACUUM 尽快运行以避免迫在眉睫的事务 ID 回卷时(见 Section 24.1.5),这可能有用。不过,由 vacuum_failsafe_age 控制的回卷失效保护机制通常会自动触发以避免事务 ID 回卷失败,应当优先使用它。如果不定期执行索引清除,性能可能会受到影响,因为随着表被修改,索引会积累死元组,而表本身会积累死行指针,这些行指针在索引清除完成之前无法被移除。
这个选项对没有索引的表没有效果,并且在使用 FULL 选项时会被忽略。它对事务 ID 回卷失效保护机制也没有影响。该机制被触发时会跳过索引清理,即使 INDEX_CLEANUP 被设置为 ON。
PROCESS_MAIN 指定 VACUUM 应当尝试处理主关系。这通常是期望的行为,也是默认行为。当只需要清理某个关系对应的 TOAST 表时,把这个选项设置为 false 可能有用。
PROCESS_TOAST 指定 VACUUM 应当尝试处理每个关系对应的 TOAST 表(如果存在)。这通常是期望的行为,也是默认行为。当只需要清理主关系时,把这个选项设置为 false 可能有用。使用 FULL 选项时必须有这个选项。
TRUNCATE 指定 VACUUM 应当尝试截断表末尾的任何空页,并允许把截断页占用的磁盘空间返还给操作系统。这通常是期望的行为,也是默认行为,除非 vacuum_truncate 被设置为 false,或者要清理的表的 vacuum_truncate 选项已被设置为 false。把这个选项设置为 false 可能有助于避免截断所需要的表上的 ACCESS EXCLUSIVE 锁。使用 FULL 选项时这个选项会被忽略。
PARALLEL 以并行方式执行 VACUUM 的索引清理和索引清除阶段,使用 integer 个后台工作者(每个清理阶段的细节请参考 Table 27.46)。用于执行该操作的工作者数量等于该关系上支持并行清理的索引数量,如果指定了 PARALLEL 选项,则受其指定的工作者数量限制,并且还进一步受 max_parallel_maintenance_workers 的限制。一个索引当且仅当其大小大于 min_parallel_index_scan_size 时才能参与并行清理。请注意,并不保证执行时会使用 integer 中指定的并行工作者数量。清理运行时使用的工作者可能少于指定数量,甚至可能完全不用工作者。每个索引只能使用一个工作者,因此只有当表中至少有 2 个索引时才会启动并行工作者。清理工作者会在每个阶段开始之前启动,并在该阶段结束时退出。这些行为在未来的版本中可能会改变。这个选项不能与 FULL 选项一起使用。
SKIP_DATABASE_STATS 指定 VACUUM 应跳过更新关于最老未冻结 XID 的数据库范围的统计信息。通常 VACUUM 会在命令结束时更新这些统计信息一次。但是,在表数量非常庞大的数据库中,这可能耗费一段时间,而且如果包含最老未冻结 XID 的表不在被清理的表之列,这样做将毫无作用。此外,如果并行发出多个 VACUUM 命令,同一时间只能有一个命令更新数据库范围的统计信息。因此,如果应用打算发出一连串大量的 VACUUM 命令,在除最后一条之外的所有命令中设置这个选项会有帮助;或者在所有命令中都设置它,然后单独发出 VACUUM (ONLY_DATABASE_STATS)。
ONLY_DATABASE_STATS 指定 VACUUM 除了更新关于最老未冻结 XID 的数据库范围的统计信息之外不做任何事。指定这个选项时,table_and_columns 列表必须为空,并且除 VERBOSE 之外不能启用任何其他选项。
BUFFER_USAGE_LIMIT 指定 缓冲区访问策略(Buffer Access Strategy)在 VACUUM 中使用的环形缓冲区大小。这个大小用于计算将作为该策略的一部分被重用的共享缓冲区数量。0 会禁用 Buffer Access Strategy 的使用。如果还指定了 ANALYZE,则 BUFFER_USAGE_LIMIT 值会同时用于清理和分析阶段。除非同时指定了 ANALYZE,否则这个选项不能与 FULL 选项一起使用。未指定这个选项时,VACUUM 会使用来自 vacuum_buffer_usage_limit 的值。更高的设置可以让 VACUUM 运行得更快,但设置过大会导致太多其他有用的页被从共享缓冲区中逐出。最小值为 128 kB,最大值为 16 GB。
boolean 指定所选选项应该被打开还是关闭。可以写 TRUE、ON 或 1 来启用该选项,写 FALSE、OFF 或 0 来禁用它。boolean 值也可以被省略,此时将假定 TRUE。
integer指定传递给所选选项的一个非负整数值。
size 指定以千字节为单位的内存量。大小也可以指定为一个字符串,其中包含数字大小,后跟以下任意一种内存单位:B(字节)、kB(千字节)、MB(兆字节)、GB(吉字节)或 TB(太字节)。
table_name 要清理的特定表或物化视图的名称(可以选择用模式限定)。如果在表名之前指定了 ONLY,则只清理该表。如果没有指定 ONLY,则还会清理该表及其所有继承子表或分区(如果有)。也可以选择在表名之后指定 *,以显式地表示要清理继承子表(或分区)。
column_name 要分析的特定列的名称。默认为所有列。如果指定了列列表,则必须同时指定 ANALYZE。
指定 VERBOSE 时,VACUUM 会发出进度消息,指示当前正在处理哪个表。同时还会打印关于这些表的各种统计信息。
要清理一个表,通常必须对该表拥有 MAINTAIN 特权。不过,数据库拥有者可以清理其数据库中的所有表,共享目录除外。VACUUM 会跳过调用用户无权清理的任何表。
在 VACUUM 运行期间,search_path 会被临时改为 pg_catalog, pg_temp。
VACUUM 不能在事务块内执行。
对于带有 GIN 索引的表,VACUUM(任何形式)还会通过把待处理的索引条目移动到主 GIN 索引结构中的适当位置,来完成所有待处理的索引插入。详情请参见 Section 65.4.4.1。
我们建议定期清理所有数据库,以移除死行。PostgreSQL 包含一个 “自动清理”(autovacuum)工具,它可以自动完成例行的清理维护。有关自动和手动清理的更多信息,请参见 Section 24.1。
不推荐在日常使用 FULL 选项,但在特殊情况下它可能有用。例如,当你已经删除或更新了表中的大部分行,并且希望该表在物理上收缩以占用更少的磁盘空间、支持更快的表扫描时。VACUUM FULL 通常会比普通 VACUUM 把表收缩得更多。
PARALLEL 选项仅用于清理。如果这个选项与 ANALYZE 选项一起指定,它不会影响 ANALYZE。
VACUUM 会导致 I/O 流量大幅增加,这可能使其他活动会话的性能变差。因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作者会按其完成的工作量成比例地休眠。详情请参见 Section 19.10.2。
每个正在运行 VACUUM(不带 FULL 选项)的后端进程都会在 pg_stat_progress_vacuum 视图中报告其进度。运行 VACUUM FULL 的后端进程则会在 pg_stat_progress_cluster 视图中报告进度。详情请参见 Section 27.4.5 和 Section 27.4.2。
清理单个表 onek,为优化器分析它,并打印详细的清理活动报告:
VACUUM (VERBOSE, ANALYZE) onek;
SQL 标准中没有 VACUUM 语句。
在 PostgreSQL 9.0 版之前使用以下语法,目前仍然支持它:
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]
注意在这种语法中,选项必须严格按所示的顺序指定。