我们的 PostgreSQL 9.0 Windows 生产服务器空间不足。
在我们 100GB 的数据库中,我们有一个包含 TOASTed 二进制数据的大表。我们已经删除了一些行,需要将空间返回给 O/S。
我们没有足够的空间来完全重写表,而我所有的阅读,CLUSTER
都是他们需要重写的表。到目前为止,我的 google-fu 还不足以找到其他任何东西。VACUUM FULL
pg_repack
一些停机时间是可以接受的(约 2 小时),但是备份/恢复对于我们的目的来说太慢了,我也不热衷于在步骤之间删除数据库。
问题:如何在不进行全表重写的情况下将磁盘空间归还给操作系统?
(这是一个生产服务器,因此任何解决方案都必须是有信誉的/推荐的/支持的等)。
(PS 如果可以以某种方式在其上重建表,则可以使用单独的更大的磁盘。表空间?)
如果您使用除
CLUSTER
//VACUUM FULL
之外的任何东西pg_repack
(所有这些都自动管理锁),您需要确保没有并发写入表。在表上获取排他锁并在单个事务中完成所有操作,或者更好的是,关闭所有连接以避免并发更改。TABLESPACE
是的,你的最后一个想法可行。在另一个磁盘上创建一个新的表空间。
然后在新表空间中创建表的优化副本:
副本将被紧紧地打包,没有死行。
然后你可能只是删除旧表并重命名新表以继续使用新磁盘。
或者,如果由于某种原因必须将其保留在旧磁盘上,请删除旧表,重命名新表并将其移回默认表空间。现在,这一步要快得多:
根据文档:
无论哪种方式,不要忘记(重新)创建所有依赖对象。索引、外键、视图……
好吧,您可以
ALTER TABLE tbl SET TABLESPACE ...
开始使用,但是表格不会按要求进行优化,只是按原样移动。但是您将有足够的回旋余地来运行 pg_repack 等。COPY
完整的备份/恢复可能需要很长时间,但您可以只对有问题的表执行此操作。
桌子现在已经挤得满满当当了。
临时表
如果您碰巧有足够的 RAM,您可以对 RAM 中的临时表执行类似的操作。会快很多。详细说明:
如果您的环境的磁盘空间超过此表的“真实数据(减少后)”大小。您可以使用 pg_reorg 减少此表的膨胀空间。或者您可以使用 londiste3 增量复制此表,并使用更少的时间进行交换。但是如果你的环境没有比这张表更多的空间,你就不能减少。
当您可以删除堆页面中的元组时,还有另一种方法可以减少膨胀空间,这种方法使用较少的添加空间来减少膨胀表。喜欢 exp:
你注意锁定,这只是一个想法。