VACUUM FULL表所需的空间

16

从PostgreSQL 10.4手册中关于完整清理(vacuum)的说明:

请注意,它们也会临时使用大约等于表大小的额外磁盘空间,因为旧版本的表和索引只有在新版本完成后才能释放

我已经在很多不同的地方读到了这个问题,并以各种方式表达。一些表明所需空间最多等于被清理表的大小。这暗示可能仅需要足够的空间来存储结果清理后的表,即大小在[0-size_of_original_table]范围内,具体取决于表中有多少死行(dead rows)。

我的问题是:对一个表进行完整清理(vacuum)是否总是需要与原始表大小相等的空间,还是取决于表中的活行(live rows)数量?

2个回答

22

VACUUM (FULL)需要的额外空间取决于表中活跃行的数量。

VACUUM (FULL)期间会写入一个新的表副本。 所有活跃元组(即行版本)和尚不能被移除的死元组都将被写入这个新副本。

事务完成后,旧的副本将被删除。


3
感谢您的纠正。因此,对于一个包含500MB存活行和500MB死亡行的1GB表,对该表进行VACUUM FULL操作将逐步分配空间并将存活行复制到新表中,直到完成,此时达到500MB?与分配1GB,复制存活行,然后返回任何多余分配的空间(在这种情况下为500MB)不同。 - Thrasi
未能在上方标记您。 - Thrasi
非常有用的答案,您可以通过查询pg_stat_user_tables(或在TOAST的情况下查询pg_stat_sys_tables https://dba.stackexchange.com/a/223225/94649)来检查有多少元组已经死亡。 - odinho - Velmont
1
@Thrasi 你理解得很正确。使用的磁盘空间并没有预先分配,而是随着新文件的写入而增加。 - Laurenz Albe

10

建议磁盘上的剩余空间至少应等于数据库中最大表的大小。

例如,如果您的数据库大小为10GB,且数据库中最大表的大小为2GB,则必须至少有2GB额外的磁盘空间,以便成功完成VACUUM操作。

因为VACUUM FULL将创建该表的新副本,但不包括死行,并随后删除现有的表。


3
建议这样做,因为如果最大的表只包含活动行,则需要那么多的空间。但是,如果你知道最大的表主要包含未使用的行,你可以少用一些空间,这是我从中得出的结论。 - Thrasi
是的,可能。如果您知道该表中存在多少活动数据,则空闲空间应该比它更多。 但是,如果此表中的活动数据大小小于其他表中的数据,则您还必须考虑所需的空间。 - Vipul Shukla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接