删除后如何回收磁盘空间而不重建表?

Bre*_*ill 4 postgresql windows disk-space vacuum postgresql-9.0

我们的 PostgreSQL 9.0 Windows 生产服务器空间不足。

在我们的 100GB 数据库中,我们有一个包含 TOAST 二进制数据的大表。我们删除了一些行,需要将空间归还给 O/S。

我们没有足够的空间做表的全部重写,所有我的读书CLUSTERVACUUM FULL而且pg_repack是他们需要重写表。到目前为止,我的 google-fu 还不足以找到其他任何东西。

一些停机时间是可以接受的(约 2 小时),但是备份/恢复对于我们的目的来说太慢了,我也不热衷于在步骤之间删除数据库。

问题:如何在不进行全表重写的情况下将磁盘空间返回给 O/S?

(这是一个生产服务器,因此任何解决方案都必须有信誉/推荐/支持等)。

(PS 可以使用一个单独的更大的磁盘,如果可以以某种方式在其上重建表。表空间?)

Erw*_*ter 5

如果你使用任何东西,但CLUSTER/ VACUUM FULL/ pg_repack(所有自动管理锁),你需要确保没有并发写入表。在表上使用排他锁并在单个事务中完成所有操作,或者更好的是,关闭所有连接以避免并发更改。

TABLESPACE

是的,你的最后一个想法可行。在另一个磁盘上创建一个新表空间。

CREATE TABLESPACE ts1 LOCATION '/data/disk2';
Run Code Online (Sandbox Code Playgroud)

然后在新表空间中创建表的优化副本:

CREATE TABLE new_tbl 
TABLESPACE ts1 AS
SELECT * FROM tbl
ORDER BY ....  -- ORDER BY is optional 
Run Code Online (Sandbox Code Playgroud)

副本将被紧密包装,没有死行。

然后您可能只是删除旧表并重命名新表以继续使用新磁盘。

或者,如果由于某种原因必须将其保留在旧磁盘上,请删除旧表,重命名新表并将其移回默认表空间。这一步现在快得多:

ALTER TABLE tbl SET TABLESPACE pg_default
Run Code Online (Sandbox Code Playgroud)

根据文档:

这种形式将表的表空间更改为指定的表空间,并将与该表关联的数据文件移动到新表空间。表上的索引(如果有)不会移动;但它们可以通过附加SET TABLESPACE命令单独移动。另见 CREATE TABLESPACE

无论哪种方式,不要忘记(重新)创建所有依赖对象。索引、外键、视图、...

好吧,您可以ALTER TABLE tbl SET TABLESPACE ...开始使用,但随后表不会按要求进行优化,只是按原样移动。但是你会有足够的回旋余地来运行 pg_repack 等。

COPY

完整的备份/恢复可能需要很长时间,但您可以只对有问题的表执行此操作。

COPY tbl TO '/path/to/other/disk/tbl.pgsql';
TRUNCATE tbl;
COPY tbl FROM '/path/to/other/disk/tbl.pgsql';
Run Code Online (Sandbox Code Playgroud)

桌子现在挤得满满当当。

临时表

如果您碰巧有足够的 RAM,您可以对 RAM 中的临时表执行类似的操作。会快很多。详细说明: