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

时间:2017-11-21 04:57:11

标签: postgresql

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

DELETE FROM v_xml_cdr;

然后使用命令\ d +检查表大小,但表v_xml_cdr的大小与之前几乎相同。

我在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 |              | 
...

有人说“vacuum full”命令会在发生此问题后缩小表格大小。

但我想知道清除表时是否有一个避免此问题的好方法,而不是使用“vacuum full”命令。

1 个答案:

答案 0 :(得分:2)

https://www.postgresql.org/docs/current/static/routine-vacuuming.html#VACUUM-FOR-SPACE-RECOVERY

  

在PostgreSQL中,行的UPDATE或DELETE不会立即生效   删除旧版本的行。获得这种方法是必要的   多版本并发控制的好处(MVCC,见章节   13):在仍然可能的情况下,不得删除行版本   对其他交易可见。但最终,一个过时或删除   任何交易都不再对行版本感兴趣。它的空间   然后必须回收占用,以便新行重用,以避免   磁盘空间需求无限增长。这是通过运行完成的   真空。

     

VACUUM的标准形式删除了表格中的死行版本   索引并标记可用于将来重用的空间。但是,它   不会将空间返回给操作系统,除了在   表格末尾的一个或多个页面成为特殊情况   完全免费,可以轻松获得独家桌锁。在   对比, VACUUM FULL通过写一个完整的主动压缩表   没有死角的新版表文件。这最小化了   表的大小,但可能需要很长时间。它还需要额外的   磁盘空间为表的新副本,直到操作   完成。

并进一步:

  

如果您有一个表,其中的所有内容都会定期删除   基础,考虑使用TRUNCATE而不是使用DELETE   然后是VACUUM。 TRUNCATE删除表格的全部内容   立即,无需后续VACUUM或VACUUM FULL   回收现在未使用的磁盘空间。缺点是违反了严格的MVCC语义。

强调我的