SQL COMMAND · 维护
VACUUM
垃圾收集并按需分析数据库
VACUUM维护引入 10(基线)现存至 20 devel7 次语法变更
- 动词
VACUUM- 对象
—- 分组
- 维护
- 引入版本
- 10(基线)
- 状态
- 现存
- 语法变更次数
- 7
- 手册小节数
- 7
版本轨迹
相对 PostgreSQL 17 语法未变,正文有更新。
语法铁道图 PostgreSQL 18
沿轨道从左向右阅读,分岔表示选择,绕行表示可选,回环表示重复。方框为参数,点击带下划线的参数可展开子规则。
option
table_and_columns
语法概要
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的索引清理(index vacuuming)和索引收尾清理(index cleanup)阶段(每个清理阶段的细节参见 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 [, ...] ]
请注意,在这种语法中,选项必须严格按所示顺序指定。
另见
语法演化
相邻大版本之间的差异,新的在前。版本号链接到对应快照。
PostgreSQL 20← 19正文更新
正文更新PostgreSQL 19← 18语法变化
+ FULL [ boolean ]+− FULL [ boolean ]正文更新PostgreSQL 18← 17正文更新
正文更新PostgreSQL 17← 16正文更新
正文更新PostgreSQL 16← 15语法变化
+ BUFFER_USAGE_LIMIT size−正文更新PostgreSQL 15← 14语法变化
+ PROCESS_MAIN [ boolean ]+ SKIP_DATABASE_STATS [ boolean ]+ ONLY_DATABASE_STATS [ boolean ]+正文更新PostgreSQL 14← 13语法变化
+ 其中option可以是下列之一:+ INDEX_CLEANUP { AUTO | ON | OFF }+ PROCESS_TOAST [ boolean ]+ 其中table_and_columns是:++ [ ONLY ] table_name [ * ] [ ( column_name [, ...] ) ]− VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]− 其中option为以下之一:− INDEX_CLEANUP [ boolean ]− 而table_and_columns为:− table_name [ ( column_name [, ...] ) ]正文更新PostgreSQL 13← 12语法变化
+ PARALLEL integer−正文更新PostgreSQL 12← 11语法变化
+ FULL [ boolean ]+ FREEZE [ boolean ]+ VERBOSE [ boolean ]+ ANALYZE [ boolean ]+ DISABLE_PAGE_SKIPPING [ boolean ]+ SKIP_LOCKED [ boolean ]+ INDEX_CLEANUP [ boolean ]+ TRUNCATE [ boolean ]− FULL− FREEZE− VERBOSE− ANALYZE− DISABLE_PAGE_SKIPPING正文更新PostgreSQL 11← 10语法变化
+ VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]+ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]++ 其中option为以下之一:++ FULL+ FREEZE+ VERBOSE+ ANALYZE+ DISABLE_PAGE_SKIPPING++ 而table_and_columns为:+ table_name [ ( column_name [, ...] ) ]− VACUUM [ ( { FULL | FREEZE | VERBOSE | ANALYZE | DISABLE_PAGE_SKIPPING } [, ...] ) ] [ table_name [ (column_name [, ...] ) ] ]− VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ table_name ]− VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table_name [ (column_name [, ...] ) ] ]正文更新
同组命令
| 命令 | 动词 | 对象 | 版本变动 | 最近变更 |
|---|---|---|---|---|
ANALYZE | ANALYZE | — | 165 次 | |
| 收集数据库的统计信息 | 现存 | |||
CHECKPOINT | CHECKPOINT | — | 191 次 | |
| 强制执行一次预写式日志检查点 | 现存 | |||
CLUSTER | CLUSTER | — | 141 次 | |
| 按照一个索引对表进行聚簇 | 现存 | |||
VACUUM | VACUUM | — | 197 次 | |
| 垃圾收集并按需分析数据库 | 现存 | |||