【问题标题】:Postgresql - large delete from 500Gb DB / auto-vacuum?Postgresql - 从 500Gb 数据库/自动真空中大量删除?
【发布时间】:2018-09-16 04:58:27
【问题描述】:

我需要删除大约 80% 的 500Gb Postgresql 数据库。 到目前为止,我已经成功地为大约 50Gb 的行运行了删除命令,并在继续之前暂停了。 (这花了很长时间,也许一个小时)

我注意到在删除大约 50Gb 的数据后,没有释放额外的磁盘空间,但是当我运行“htop”时可以观察到一些内存密集型 postgres 进程。我是否正确假设这是死行,需要在释放磁盘空间之前对其进行清理?

这个问题的第二部分是,如果我没记错第一部分,我最好删除所有行,然后允许自动真空发生吗?在我有机会继续我的行删除命令列表之前,似乎自动真空(或其他一些密集的后台进程)已经自行启动。我应该继续还是应该优雅地告诉它先停止?

【问题讨论】:

  • autovacuum 不执行vacuum full - 因此它不一定会释放已删除的元组磁盘空间,但会将它们标记为可重用。是的 - 这是正常的。不 - 你不应该关心它 - 继续你的工作,让 autovacuum 来执行它

标签: postgresql vacuum autovacuum


【解决方案1】:

大删除后,autovacuum 肯定会运行。这是设计的,不应干扰您删除更多行。

虽然 autovacuum 会释放表中的死空间,但它不会将空间返回给操作系统。相反,它作为空闲空间保留在表中,可以在以后的插入中重复使用。

如果您想缩小表,请在它们上运行VACUUM (FULL),但要注意这会重写表,因此它会暂时使用额外的存储空间并阻止表上的所有并发活动。

如果您必须定期进行这样的批量删除,请考虑对表进行分区。它使批量删除变得轻松。

【讨论】:

    【解决方案2】:

    更好的解决方案是TRUNCATE table。

    在我的场景中,我删除了占用大量磁盘空间的特定行,但对于 VACUUM 而言,数据太多,无法在合理的时间内清除。

    我最终复制了表格:

    CREATE table dupe_table AS (SELECT * FROM table);
    

    截断原始表:

    TRUNCATE table
    

    最后将数据移回:

    INSERT INTO table(column1, column2, column3)
    SELECT column1, column2, column3
    FROM dupe_table
    

    注意:如果您在创建重复表和截断原始表之间发生事务,您可能会丢失数据

    【讨论】:

      猜你喜欢
      • 2016-01-13
      • 1970-01-01
      • 2016-11-20
      • 1970-01-01
      • 2019-03-18
      • 2020-06-03
      • 2014-07-29
      • 2019-04-01
      • 1970-01-01
      相关资源
      最近更新 更多