↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1 / 7.0
开发快照。 PostgreSQL 20devel 尚未正式发布,内容仍可能变化。

VACUUM

VACUUM — 垃圾收集并按需分析数据库

大纲

VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]

其中option可以是下列之一:

    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 ]
    PARALLEL integer
    SKIP_DATABASE_STATS [ boolean ]
    ONLY_DATABASE_STATS [ boolean ]
    BUFFER_USAGE_LIMIT size
    FULL [ boolean ]

其中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。如需禁用该功能,可以使用 PARALLEL 选项并将并行工作进程数指定为零。VACUUM FULL 会把表的全部内容重写到一个没有额外空闲空间的新磁盘文件中,从而让未使用的空间能够返还给操作系统。这种形式要慢得多,并且在处理每个表时都需要 ACCESS EXCLUSIVE 锁。

参数

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 回卷时,这可能会有用(参见第 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 #

指定可用于 Parallel Vacuum 的最大并行工作进程数,其数量还会进一步受到 max_parallel_maintenance_workers 的限制。此选项不能与 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 表示禁用缓冲区访问策略。如果同时指定了 ANALYZE,那么 BUFFER_USAGE_LIMIT 的值会同时用于清理阶段和分析阶段。除非也指定了 ANALYZE,否则该选项不能与 FULL 一起使用。如果未指定该选项,VACUUM 会使用 vacuum_buffer_usage_limit 中的值。更高的设置可以让 VACUUM 运行得更快,但设置过大可能会把过多其他有用页面从共享缓冲区中逐出。最小值是 128 kB,最大值是 16 GB。

FULL #

该选项已弃用,它会使 VACUUM 的行为类似于不带 USING INDEX 子句的 REPACK。这种表压实方法比 VACUUM 耗时长得多,并且会独占锁定该表。这种方法还需要额外的磁盘空间,因为它会写出该表的一个新副本,并且在操作完成之前不会释放旧副本。通常,只有当需要从表内回收大量空间时才应使用这种方法。

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 会以 INFO 级别输出清理各表的详细信息,包括当前正在处理哪个表以及这些表的各种统计信息。

注解

要清理一个表,通常必须拥有该表上的 MAINTAIN 权限。不过,数据库拥有者可以清理其数据库中的所有表,但共享系统目录除外。VACUUM 会跳过调用用户无权清理的任何表。

当 VACUUM 运行时,search_path 会被临时改为 pg_catalog, pg_temp。

VACUUM 不能在一个事务块内被执行。

对于带有 GIN 索引的表,VACUUM(任何形式)还会通过把待处理的索引项移动到主 GIN 索引结构中的适当位置,来完成所有挂起的索引插入。详见第 65.4.4.1 节。

我们建议定期对所有数据库执行清理,以移除死行。PostgreSQL 提供了一个“自动清理(autovacuum)”机制,可以自动执行常规清理维护。有关自动与手动清理的更多信息,参见第 24.1 节。

FULL 选项不建议在日常场景中使用,但在某些特殊情况下可能很有用。例如,当你删除或更新了表中的绝大多数行,并希望该表在物理上收缩以占用更少磁盘空间、让表扫描更快时,这个选项就比较合适。VACUUM FULL 通常会比普通 VACUUM 更大幅度地收缩表。

PARALLEL 选项只用于清理。如果此选项与 ANALYZE 选项一起指定,它不会影响 ANALYZE。

VACUUM 会显著增加 I/O 流量,这可能导致其他活动会话性能变差。因此,有时建议使用基于代价的清理延迟特性。对于并行清理,每个工作进程的睡眠时长都与该工作进程完成的工作量成比例。详见第 19.10.2 节。

每个运行不带 FULL 选项的 VACUUM 的后端,都会在 pg_stat_progress_vacuum 视图中报告其进度。运行 VACUUM FULL 的后端则会改为在 pg_stat_progress_cluster 视图中报告其进度。详见第 27.4.6 节和第 27.4.2 节。

示例

清理单个表 onek,对其进行分析以供优化器使用,并打印清理和分析的详细信息:

VACUUM (VERBOSE, ANALYZE) onek;

兼容性

在 SQL 标准中没有 VACUUM 语句。

下列语法在 PostgreSQL 9.0 版本之前使用,并且目前仍受支持:

VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]

请注意,在这种语法中,选项必须严格按所示顺序指定。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.