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 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
针对每个表打印详细的清理活动报告。
ANALYZE
更新计划程序用来确定执行查询的最有效方法的统计数据。
DISABLE_PAGE_SKIPPING
通常来说,VACUUM
将根据可见性映射来跳过页面。所有元组均已冻结的页面始终都可以跳过,而所有元组均对所有事务可见的页面(执行彻底清理除外)也可以跳过。此外(执行彻底清理除外),可以跳过一些页面以避免等待其他会话完成对这些页面的使用。此选项禁用所有跳页行为,仅在怀疑可见性映射的内容时使用,并且仅在硬件或软件问题导致数据库损坏时才会发生这种情况。
SKIP_LOCKED
指定VACUUM
在开始对关系执行工作时不应该等待任何冲突锁的释放:如果关系无法立即锁定而无需等待,则跳过该关系。请注意,即使有此选项,VACUUM
在打开关系索引时仍然可能会阻塞。另外,VACUUM ANALYZE
在从分区、表继承子项和某些类型的外部表获取样本行时仍可能阻塞。同时,虽然VACUUM
通常会处理指定的分区表的全部分区,但是,如果分区表上存在冲突锁,此选项将导致VACUUM
跳过所有分区。
INDEX_CLEANUP
通常来说,当表中死元组非常少时,VACUUM
将跳过索引清理。这时,处理表所有索引的成本预计将远远超过删除死索引元组带来的好处。此选项可以强制VACUUM
在死元组多于 0 个时处理索引。默认值为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 以用于要清理的表。将此选项设置为 false 可能有助于避免对表进行清理所需的 ACCESS EXCLUSIVE
锁。如果使用了 FULL
选项,此选项将被忽略。
并行
并行执行VACUUM
的索引真空和索引清理阶段,使用整数
个后台工作进程(有关每个真空阶段的详细信息,请参阅表 27.46)。用于执行该操作的工作进程数等于关系上的索引数,该索引支持并行 vacuum,该数量受使用PARALLEL
选项(如果有的话)指定的进程数的限制,而该数量又受max_parallel_maintenance_workers的限制。当且仅当索引大小大于min_parallel_index_scan_size时,才能针对该索引进行并行真空。请注意,并行工作进程中指定的整数
的数目在执行期间并非一定使用。vacuum 可能会使用比指定数目更少的进程,甚至是完全不使用进程运行。2
个索引时才会启动并行进程,因此每个索引只能使用一个工作进程。在每个阶段开始之前都会启动 vacuum 工作进程,并在该阶段结束时退出进程。此类行为在将来版本中可能会发生改变。此选项不能与FULL
选项一起使用。
SKIP_DATABASE_STATS
指定VACUUM
应跳过更新有关最旧未冻结 XID 的数据库级统计信息。通常情况下,VACUUM
将在命令结束时一次更新这些统计信息。但是,在包含许多表的数据库中可能需要一段时间,而且,除非包含最旧未冻结 XID 的表是经过 vacuum 的表中之一,否则它根本无法完成。此外,如果并行发出多个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
。
布尔值
指定应开启还是关闭所选选项。可以写入 TRUE
、ON
或 1
以启用该选项,写入 FALSE
、OFF
或 0
以禁用该选项。也可以省略
值,此时将假设为 boolean
TRUE
。
整数
指定传递给所选选项的非负整数值。
大小
指定以千字节为单位的内存量。大小还可以指定为一个字符串,字符串中包含数字大小,后面跟有以下任一内存单位:B
(字节)、kB
(千字节)、MB
(兆字节)、GB
(千兆字节)或 TB
(太字节)。
table_name
要清除的具体表或物化视图的名称(可选择用模式限定)。如果指定了表是分区表,则其全部叶分区都会被清除。
column_name
要分析的具体列的名称。默认为所有列。如果指定了列列表,还必须指定 ANALYZE
。
指定 VERBOSE
时,VACUUM
将发出进度消息以指示当前正在处理哪个表。还会打印关于各表的各种统计信息。
通常,要对表执行 VACUUM,必须在该表上有 MAINTAIN
权限。但是,数据库所有者可以对数据库中除了共享目录之外的所有表执行 VACUUM。 VACUUM
将跳过任何调用用户没有权限执行 VACUUM 的表。
运行 VACUUM
时,search_path 会临时更改为 pg_catalog, pg_temp
。
VACUUM
不能在事务块内执行。
对于有GIN索引的表,VACUUM
(任何形式)还会通过将未决索引项移动到主GIN索引结构中的适当位置,完成任何未决索引插入。有关详细信息,请参阅 第 64.4.4.1 节。
我们建议定期对所有数据库执行 VACUUM,以删除死行。PostgreSQL 包含一个 “autovacuum” 工具,它可以自动进行例程性 VACUUM 维护。有关自动和手动 VACUUM 的更多信息,请参阅 第 24.1 节。
不建议常规使用 FULL
选项,但它在特殊情况下可能有用。例如,当您已删除或更新表中的大多数行,并希望表物理收缩以占据更少的磁盘空间并允许更快的表扫描时。VACUUM FULL
通常比普通 VACUUM
收缩表更多。
PARALLEL
选项仅用于 VACUUM 目的。如果此选项与 ANALYZE
选项一起指定,它不会影响 ANALYZE
。
VACUUM
会导致 I/O 流量大幅增加,这可能会导致其他活动会话的性能下降。因此,有时建议使用基于成本的 VACUUM 延迟功能。对于并行 VACUUM,每个工作程序休眠时间与该工作程序完成的工作成比例。有关详细信息,请参阅 第 19.4.4 节。
每个运行 VACUUM
的后端(不带 FULL
选项)会在 pg_stat_progress_vacuum
视图中报告其进度。运行 VACUUM FULL
的后端会在 pg_stat_progress_cluster
视图中报告其进度。有关详细信息,请参阅 第 27.4.5 节 和 第 27.4.2 节。
要清理单个表 onek
,对它进行优化器分析,并打印详细的 VACUUM 活动报告
VACUUM (VERBOSE, ANALYZE) onek;
SQL 标准中没有 VACUUM
语句。
以下语法在 PostgreSQL 9.0 版之前使用,并且仍然受支持
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns
[, ...] ]
请注意,在此语法中,选项必须按照显示的顺序指定。