VACUUM — 垃圾收集并按需分析数据库
VACUUM [ (option[, ...] ) ] [table_and_columns[, ...] ] 其中option可以是下列之一: 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_LIMITsize其中table_and_columns是: [ ONLY ]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锁。
FULL #选择“完全”清理,它可以回收更多空间,但耗时更长,并且会独占锁定该表。 这种方法还需要额外的磁盘空间,因为它会写出该表的一个新副本,并且在操作完成之前 不会释放旧副本。通常,只有当需要从表内回收大量空间时才应使用这种方法。
FREEZE #选择激进的元组“冻结”。指定FREEZE 等价于执行一个将vacuum_freeze_min_age和 vacuum_freeze_table_age参数设为零的 VACUUM。在表被重写时总会执行激进冻结,因此指定了 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 #使用integer个后台工作进程并行执行 VACUUM的清理索引阶段和清除索引阶段(每个清理阶段的细节参见 Table 27.43)。实际用于执行操作的工作进程数量,等于该关系上支持并行清理的索引数量, 该数量受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 #指定VACUUM所使用的 缓冲区访问策略(Buffer Access Strategy) 环形缓冲区大小。该大小用于计算在此策略中会被重用的共享缓冲区数量。 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.4.4。
每个运行不带FULL选项的VACUUM的后端,都会在 pg_stat_progress_vacuum视图中报告其进度。 运行VACUUM FULL的后端则会改为在 pg_stat_progress_cluster视图中报告其进度。详见 Section 27.4.3和Section 27.4.4。
清理单个表onek,对其执行优化器分析,并打印详细的清理活动报告:
VACUUM (VERBOSE, ANALYZE) onek;
在SQL标准中没有VACUUM语句。
下列语法在PostgreSQL 9.0版本之前使用,并且目前仍受支持:
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]
请注意,在这种语法中,选项必须严格按所示顺序指定。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。