VACUUM

名称

VACUUM -- 垃圾收集并根据需要分析一个数据库

大纲

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 [, ...] ) ] ]

描述

VACUUM收回由死亡元组占用的存储空间。在通常的PostgreSQL操作中,被删除或者被更新废弃的元组并没有在物理上从它们的表中移除,它们将一直存在直到一次VACUUM被执行。因此有必要周期性地做VACUUM,特别是在频繁被更新的表上。

在不带任何参数的情况下,VACUUM会处理当前用户具有清理权限的当前数据库中的每一个表。通过使用一个参数,VACUUM可以只处理指定表。

VACUUM ANALYZE对每一个选定的表ANALYZE。这是两种命令的一种方便的组合形式,可以用于例行的维护脚本。其处理细节可参考ANALYZE

简单的 VACUUM(不带FULL)简单地收回空间并使其可以被重用。这种形式的命令可以和表的普通读写操作并行,因为它不会获得一个排他锁。但是,这种形式中额外的空间并没有被还给操作系统(在大多数情况下),它仅仅被保留在同一个表中以备重用。VACUUM FULL将表的整个内容重写到一个新的磁盘文件中,并且不包含额外的空间,这使得没有被使用的空间被还给操作系统。这种形式的命令更慢并且在其被处理时要求在每个表上保持一个排他锁。

当选项列表被包围在圆括号中时,选项可以被写成任何顺序。如果没有圆括号,选项必须严格按照上面所展示的顺序指定。有圆括号的语法在PostgreSQL 9.0时被加入,无圆括号的语法则被废弃。

参数

FULL

选择"完全"清理,它可以收回更多空间,并且需要更长时间和表上的排他锁。这种方法还需要额外的磁盘空间,因为它会创建该表的一个新拷贝,并且在操作完成之前都不会释放旧的拷贝。通常这种方法只用于需要从表中收回数量庞大的空间时。

FREEZE

选择激进的元组"冻结"。指定FREEZE 等价于参数vacuum_freeze_min_agevacuum_freeze_table_age设置为0的 VACUUM。当表被重写时总是会执行激进的冻结, 因此指定FULL时这个选项是多余的。

VERBOSE

为每个表打印一份详细的清理活动报告。

ANALYZE

更新优化器用以决定最有效执行一个查询的方法的统计信息。

DISABLE_PAGE_SKIPPING

通常,VACUUM将基于可见性映射跳过页面。已知所有元组都被冻结的页面总是会被跳过,而那些所有元组对所有事务都可见的页面则可能会被跳过(除非执行的是激进的清理)。此外,除非在执行激进的清理时,一些页面也可能会被跳过,这样可避免等待其他页面完成对其使用。这个选项禁用所有的跳过页面的行为,其意图是只在可见性映射内容值得怀疑时使用,这种情况只有在硬件或者软件问题导致数据库损坏时才会发生。

table_name

要清理的表的名称(可以有模式修饰)。缺省时是当前数据库中的所有表。

column_name

要分析的指定列的名称。缺省是所有列。如果指定了一个列的列表,则隐含了ANALYZE

输出

如果声明了VERBOSEVACUUM会发出进度消息来表明当前正在处理哪个表。各种有关这些表的统计信息也会打印出来。

注意

要清理一个表,操作者通常必须是表的拥有者或者超级用户。但是,数据库拥有者被允许清理他们的数据库中除了共享目录之外的所有表(对于共享目录的限制意味着一个真正的数据库范围的VACUUM只能被超级用户执行)。VACUUM将会跳过执行者不具备清理权限的表。

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

对具有GIN索引的表,VACUUM(任何形式)也会通过将待处理索引项移动到主要GIN索引结构中的合适位置来完成任何待处理的索引插入。详见第 63.4.1 节

我们建议经常清理活动的生产数据库(至少每晚一次),以保证移除失效的行。在增加或删除了大量行之后, 对受影响的表执行VACUUM ANALYZE命令是一个很好的做法。这样做将把最近的更改更新到系统目录,并且允许 PostgreSQL查询规划器在规划用户查询时做出更好的选择。

日常使用时,不推荐FULL选项,但在特殊情况时它会有用。一个例子是当你删除或者更新了一个表中的绝大部分行时,如果你希望在物理上收缩表以减少磁盘空间占用并且允许更快的表扫描,则该选项是比较合适的。VACUUM FULL通常会比简单VACUUM更多地收缩表。

VACUUM会导致I/O流量的大幅度增加,这可能导致其他活动会话性能变差。因此,有时建议使用基于代价的清理延迟特性。详情请参阅第 19.4.4 节

PostgreSQL包括了一个"autovacuum"工具,它可以自动进行例行的清理维护。关于自动和手动清理的更多信息请见第 24.1 节

例子

下面是一个例子,它在regression数据库中的一个表上运行VACUUM

regression=# VACUUM (VERBOSE, ANALYZE) onek;
INFO:  vacuuming "public.onek"
INFO:  index "onek_unique1" now contains 1000 tuples in 14 pages
DETAIL:  3000 index tuples were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.01s/0.08u sec elapsed 0.18 sec.
INFO:  index "onek_unique2" now contains 1000 tuples in 16 pages
DETAIL:  3000 index tuples were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.00s/0.07u sec elapsed 0.23 sec.
INFO:  index "onek_hundred" now contains 1000 tuples in 13 pages
DETAIL:  3000 index tuples were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.01s/0.08u sec elapsed 0.17 sec.
INFO:  index "onek_stringu1" now contains 1000 tuples in 48 pages
DETAIL:  3000 index tuples were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.01s/0.09u sec elapsed 0.59 sec.
INFO:  "onek": removed 3000 tuples in 108 pages
DETAIL:  CPU 0.01s/0.06u sec elapsed 0.07 sec.
INFO:  "onek": found 3000 removable, 1000 nonremovable tuples in 143 pages
DETAIL:  0 dead tuples cannot be removed yet.
There were 0 unused item pointers.
Skipped 0 pages due to buffer pins.
0 pages are entirely empty.
CPU 0.07s/0.39u sec elapsed 1.56 sec.
INFO:  analyzing "public.onek"
INFO:  "onek": 36 pages, 1000 rows sampled, 1000 estimated total rows
VACUUM

兼容性

在SQL标准中没有VACUUM语句。

参见

vacuumdb, 第 19.4.4 节, 第 24.1.6 节