PostgreSQL:如何清除Toast表中包含某些列的表



当我使用此命令清除表(名称为v_xml_cdr)时:

DELETE FROM v_xml_cdr;

然后用命令\d+检查表的大小,但表v.xmlcdr的大小与以前几乎相同。

我在stackoverflow中搜索,发现这是因为Toast表,一些列(如Text类型)使用扩展存储,PostgreSQL将它们视为blob,并使用Toast表来存储实际数据。

d+ v_xml_cdr
Table "public.v_xml_cdr”
Column         |            Type             | Modifiers | Storage  | Stats target | Description 
------------------------+-----------------------------+-----------+----------+--------------+-------------
uuid                   | uuid                        | not null  | plain    |              | 
domain_uuid            | uuid                        |           | plain    |              | 
extension_uuid         | uuid                        |           | plain    |              | 
domain_name            | text                        |           | extended |              | 
accountcode            | text                        |           | extended |              | 
direction              | text                        |           | extended |              | 
...

有人说,在这个问题发生后,"真空满"命令可以缩小桌子的大小。

但我想知道,在清理桌子时,除了使用"真空满"命令之外,是否有一个好方法可以避免这个问题。

https://www.postgresql.org/docs/current/static/routine-vacuuming.html#VACUUM-用于空间回收的

在PostgreSQL中,一行的UPDATE或DELETE不会立即执行删除该行的旧版本。这种方法对于获得多版本并发控制的好处(MVCC,请参阅第章13) :行版本仍可能被删除时,不得将其删除其他交易可见。但最终,一个过时或删除行版本不再对任何事务感兴趣。它的空间然后必须回收占用以供新行重用,以避免磁盘空间需求的无限增长。这是通过运行真空。

VACUUM的标准形式删除了表和索引并标记可供将来重用的空间。然而不会将空间返回到操作系统,除非表末尾的一个或多个页面变为可以容易地获得完全免费和独占的表锁。在里面相反,VACUUM FULL通过编写完整的没有死区的表文件的新版本。这将桌子的大小,但可能需要很长时间。它还需要额外的表的新副本的磁盘空间,直到操作完成。

以及其他:

如果您有一个表,其全部内容都会定期删除请考虑使用TRUNCATE而不是使用DELETE然后是真空TRUNCATE删除表的全部内容立即执行,而不需要后续的"真空"或"真空满">回收现在未使用的磁盘空间。缺点是违反了严格的MVCC语义。

emphasis mine

最新更新