VACUUM — 回收数据库空间并可选地进行分析
VACUUM [ (option
[, ...] ) ] [table_and_columns
[, ...] ] whereoption
can 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
] PARALLELinteger
SKIP_DATABASE_STATS [boolean
] ONLY_DATABASE_STATS [boolean
] BUFFER_USAGE_LIMITsize
andtable_and_columns
is:table_name
[ (column_name
[, ...] ) ]
VACUUM
回收由死元组占用的存储空间。在正常的 PostgreSQL 操作中,被删除或被更新操作取代的元组不会被物理地从其表中删除;它们会保留在那里,直到执行 VACUUM
。因此,有必要定期执行 VACUUM
,尤其是在经常更新的表上。
如果没有 table_and_columns
列表,VACUUM
会处理当前数据库中当前用户有权限执行 vacuum 操作的每个表和物化视图。如果有列表,VACUUM
只会处理那些表。
VACUUM ANALYZE
会执行 VACUUM
,然后对每个选定的表执行 ANALYZE
。这是一种用于日常维护脚本的便捷组合形式。有关其处理的更多详细信息,请参阅 ANALYZE。
普通的 VACUUM
(不带 FULL
)只会回收空间并使其可供重复使用。此形式的命令可以在表正常读写时并行运行,因为它不会获取排他锁。但是,额外的空间不会返回给操作系统(在大多数情况下);它只是保留下来,供同一表内重复使用。它还允许我们利用多个 CPU 来处理索引。此功能称为 并行 vacuum。要禁用此功能,可以使用 PARALLEL
选项并将并行工作程序指定为零。 VACUUM FULL
会将表的整个内容重新写入一个新的磁盘文件,不保留任何额外的空间,从而允许将未使用的空间返回给操作系统。此形式要慢得多,并且在处理每个表时需要获取一个 ACCESS EXCLUSIVE
锁。
FULL
选择 “完整” vacuum,它可以回收更多空间,但需要更长时间,并且会对表进行排他锁定。此方法还需要额外的磁盘空间,因为它会写入表的副本,并且在操作完成之前不会释放旧副本。通常,只有在需要从表中回收大量空间时才应该使用它。
FREEZE
选择对元组进行积极的 “冻结”。指定 FREEZE
等同于执行 VACUUM
,并将 vacuum_freeze_min_age 和 vacuum_freeze_table_age 参数设置为零。当表被重写时,总是会执行积极的冻结,因此当指定 FULL
时,此选项是多余的。
VERBOSE
为每个表打印详细的 vacuum 活动报告。
ANALYZE
更新规划器用来确定执行查询的最有效方式的统计信息。
DISABLE_PAGE_SKIPPING
通常,VACUUM
会根据 可见性映射 来跳过页面。所有元组都知道已被冻结的页面总是可以跳过,而所有元组都知道对所有事务可见的页面也可以跳过,除非执行积极的 vacuum。此外,除了执行积极的 vacuum 时,还可以跳过一些页面,以避免等待其他会话完成对它们的访问。此选项会禁用所有页面跳过行为,并且仅在可见性映射的内容可疑时使用,这应该只发生在存在导致数据库损坏的硬件或软件问题时。
SKIP_LOCKED
指定 VACUUM
在开始处理关系时不应等待任何冲突的锁释放:如果关系无法立即锁定而无需等待,则会跳过该关系。请注意,即使使用此选项,VACUUM
在打开关系的索引时仍然可能会阻塞。此外,VACUUM ANALYZE
在从分区、表继承子项和某些类型的外部表获取样本行时仍然可能会阻塞。另外,虽然 VACUUM
通常会处理指定的分区表的全部分区,但此选项会导致 VACUUM
如果分区表上存在冲突的锁,则跳过所有分区。
INDEX_CLEANUP
通常,当表中只有很少的死元组时,VACUUM
会跳过索引 vacuum。当发生这种情况时,处理所有表的索引的成本预计会大大超过删除死索引元组的好处。此选项可用于强制 VACUUM
在有超过零个死元组时处理索引。默认值为 AUTO
,这允许 VACUUM
在适当的时候跳过索引 vacuum。如果 INDEX_CLEANUP
设置为 ON
,VACUUM
会保守地从索引中删除所有死元组。这可能对与早期版本的 PostgreSQL 向后兼容有用,在早期版本中,这是标准行为。
INDEX_CLEANUP
也可以设置为 OFF
,以强制 VACUUM
始终 跳过索引 vacuum,即使表中有许多死元组也是如此。这在必须使 VACUUM
尽可能快地运行以避免即将到来的事务 ID 缠绕时可能有用(请参阅 第 24.1.5 节)。但是,由 vacuum_failsafe_age 控制的缠绕故障安全机制通常会自动触发以避免事务 ID 缠绕故障,并且应优先使用。如果索引清理没有定期执行,性能可能会受到影响,因为随着表的修改,索引会累积死元组,而表本身也会累积无法在完成索引清理之前删除的死行指针。
此选项对没有索引的表没有影响,并且如果使用了 FULL
选项,则会忽略它。它对事务 ID 缠绕故障安全机制也没有影响。当触发时,它会跳过索引 vacuum,即使 INDEX_CLEANUP
设置为 ON
也是如此。
PROCESS_MAIN
指定 VACUUM
应该尝试处理主关系。这通常是期望的行为,也是默认行为。将此选项设置为 false 可能有用,因为只需要 vacuum 关系对应的 TOAST
表。
PROCESS_TOAST
指定 VACUUM
应该尝试处理每个关系对应的 TOAST
表(如果存在)。这通常是期望的行为,也是默认行为。将此选项设置为 false 可能有用,因为只需要 vacuum 主关系。当使用 FULL
选项时,此选项是必需的。
TRUNCATE
指定 VACUUM
应该尝试截断表末尾的任何空页面,并允许将截断页面的磁盘空间返回给操作系统。这通常是期望的行为,也是默认行为,除非 vacuum_truncate
选项已对要 vacuum 的表设置为 false。将此选项设置为 false 可能有用,以避免截断需要的对表的 ACCESS EXCLUSIVE
锁。如果使用了 FULL
选项,则会忽略此选项。
PARALLEL
使用 integer
个后台工作程序并行执行 VACUUM
的索引 vacuum 和索引清理阶段(有关每个 vacuum 阶段的详细信息,请参阅 表 27.46)。用于执行操作的工作程序数量等于支持并行 vacuum 的关系上的索引数量,该数量受 PARALLEL
选项指定的 worker 数量限制(如果有),该数量进一步受 max_parallel_maintenance_workers 限制。只有当索引的大小超过 min_parallel_index_scan_size 时,索引才能参与并行 vacuum。请注意,不能保证在执行过程中会使用 integer
中指定的并行 worker 数量。vacuum 可能使用的工作程序比指定的少,甚至可能一个工作程序也不使用。每个索引只能使用一个工作程序。因此,只有当表中至少有 2
个索引时才会启动并行工作程序。vacuum 的工作程序会在每个阶段开始之前启动,并在阶段结束时退出。这些行为可能会在将来的版本中发生变化。此选项不能与 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
。此大小用于计算将被用作此策略的一部分的共享缓冲区数量。 0
禁用 Buffer Access Strategy
的使用。如果还指定了 ANALYZE
,则 BUFFER_USAGE_LIMIT
值用于清理和分析阶段。此选项不能与 FULL
选项一起使用,除非还指定了 ANALYZE
。当未指定此选项时,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
要清理的特定表或物化视图的名称(可选地限定模式)。如果指定的表是分区表,则会清理其所有叶分区。
column_name
要分析的特定列的名称。默认为所有列。如果指定了列列表,则还必须指定 ANALYZE
。
当指定 VERBOSE
时,VACUUM
会发出进度消息以指示当前正在处理哪个表。还会打印有关这些表的各种统计信息。
要清理一个表,通常必须对该表拥有 MAINTAIN
权限。但是,数据库所有者可以清理其数据库中的所有表,除了共享目录。 VACUUM
将跳过调用用户没有权限清理的任何表。
在 VACUUM
运行时,search_path 将临时更改为 pg_catalog, pg_temp
。
VACUUM
无法在事务块内执行。
对于具有GIN索引的表,VACUUM
(任何形式)也会完成所有挂起的索引插入,方法是将挂起的索引条目移动到主索引结构中的适当位置。GIN有关详细信息,请参见 第 64.4.4.1 节。
我们建议定期清理所有数据库,以删除死亡行。 PostgreSQL 包含一个名为 “autovacuum” 的工具,它可以自动执行例行清理维护。有关自动和手动清理的更多信息,请参见 第 24.1 节。
FULL
选项不建议用于日常使用,但在特殊情况下可能有用。例如,当您删除或更新了表中的大多数行,并且希望表在物理上缩小以占用更少的磁盘空间并允许更快地进行表扫描时。 VACUUM FULL
通常比简单的 VACUUM
更能缩小表。
PARALLEL
选项仅用于清理目的。如果与 ANALYZE
选项一起指定,则不会影响 ANALYZE
。
VACUUM
会导致 I/O 流量大幅增加,这可能会导致其他活动会话的性能下降。因此,有时建议使用基于成本的清理延迟功能。对于并行清理,每个工作进程的睡眠时间与其完成的工作量成正比。有关详细信息,请参见 第 19.4.4 节。
每个运行 VACUUM
的后端(不带 FULL
选项)将在 pg_stat_progress_vacuum
视图中报告其进度。运行 VACUUM FULL
的后端将在 pg_stat_progress_cluster
视图中报告其进度。有关详细信息,请参见 第 27.4.5 节 和 第 27.4.2 节。
要清理单个表 onek
,分析它以供优化器使用并打印详细的清理活动报告
VACUUM (VERBOSE, ANALYZE) onek;
SQL 标准中没有 VACUUM
语句。
在 PostgreSQL 版本 9.0 之前使用了以下语法,并且仍然受支持
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns
[, ...] ]
请注意,在此语法中,必须按显示的顺序精确地指定选项。
如果您在文档中看到任何不正确的内容,与您对特定功能的体验不符或需要进一步说明,请使用 此表格 报告文档问题。