PostgreSQL:如何在 ALTER TABLE 失败后清理整个磁盘 space?

PostgreSQL: how to clean up full disk space after unsuccessful ALTER TABLE?

我在 DigitalOcean 上有一个 PostgreSQL 实例。 table的一部分存储在单独机器(块卷)上的tablespace中。

当我尝试更改 Django 中的某些字段时,大约 90% 的块卷已满。由于可用的小磁盘 space,我的命令无法成功。进程一被杀死,我就看到我的块体积 100% 满了。

问题是,如何计算出 table 的 已经消耗了可用的 space 的 10%。我相信这些是 Postgres 在迁移失败期间创建的一些系统 tables 或临时 tables,我可以通过 ftp.[=12 查看最后一天创建的原始文件=]

我需要做一些事情来清理 space 到以前的水平。

I tried altering some fields ... My command was unable to succeed

Postgres 在更新任何内容时写入新的行版本。当事务成功(提交)时,那些变得可见并且旧行版本一旦没有旧事务仍然存在就死了运行。

如果您的事务失败(很明显),事务将被回滚,那些新的行版本本身变成死元组。

这就是 PostgreSQL MVCC model. Use VACUUM 释放被死元组占用的磁盘 space 的本质。如果您失败的操作主要占用包含您的 table 的文件的物理末尾的数据页,则普通 VACUUM 可能能够释放 space 的部分或全部。 (这将是幸运的,因为 VACUUMVACUUM FULL 侵入性更小且便宜得多。)否则你需要 VACUUM FULL:

VACUUM FULL tablename;

获取独占锁,大 tables 也可能需要一些时间!

如果 autovacuum 是 运行(默认情况下应该如此),可能会在一段时间后自动释放一些 space。

VACUUM FULL重写了整个table,所以它需要大量的自由space作为“回旋余地”。你显然没有足够的,所以阅读这个相关答案中的“磁盘已满”一章:

TABLESPACE?

多一个选择。您提到:

tablespaces on a separate machine

如果另一个 TABLESPACE 上有足够的空闲 space,您可以(暂时)将 tablespace 更改为 table,这结果将 table 迁移到不同的存储位置。 ALTER TABLE 可以做到:

This form changes the table's tablespace to the specified tablespace and moves the data file(s) associated with the table to the new tablespace. Indexes on the table, if any, are not moved; but they can be moved separately with additional SET TABLESPACE commands.

所以:

ALTER TABLE name SET TABLESPACE new_tablespace;

默认tablespace的名称默认为pg_default(原文如此!)。如有疑问,请阅读 chapter "Tablespaces" in the manual.

pg_dump/恢复

如果一切都失败了,转储恢复循环可以拯救你,因为它隐含地删除了所有死元组并在原始条件下重写 table。