我有一张桌子占用了我们服务器上接近90%的高清空间。我决定删除几列以释放空间。但是我需要将空间返回给操作系统。但是,问题是我不确定如果我运行VACUUM FULL并且没有足够的可用空间来复制表,会发生什么情况。

我知道不应使用VACUUM FULL,但我认为这是这种情况下的最佳选择。

任何想法都会受到赞赏。 >我正在使用PostgreSQL 9.0.6

#1 楼

由于您没有足够的空间来运行真空或重建数据库,因此您始终可以通过还原数据库来重建它们。还原数据库,表,索引将释放空间和碎片整理。之后,您可以设置自动维护以定期清理数据库。

1备份Postgresql服务器上的所有数据库

您将需要将所有数据库备份到具有足够空间的分区。如果您使用的是Linux,则可以使用gzip进一步压缩备份以节省空间

su - postgres
pg_dumpall | gzip -9 > /some/partition/all.dbs.out.gz


2备份配置文件

cp /path/to/postgresql/data_directory/*.conf /some/partition/


3停止Postgresql

pg_ctl -D /path/to/postgresql/data_directory stop


4删除数据目录的内容

rm -Rf /path/to/postgresql/data_directory/*


5运行initdb重新初始化数据目录

initdb -D /path/to/postgresql/data_directory


6恢复配置文件

cp /some/partition/*.conf /path/to/postgresql/data_directory/*.conf 


7开始Postgresql

pg_ctl -D /path/to/postgresql/data_directory start


8恢复所有已创建数据库的转储

gunzip /some/partition/all.dbs.out.gz
psql -f /some/partition/all.dbs.out


评论


谢谢,这是我最后要做的,有一些不同。我只是在备份后删除了数据库。然后创建一个新的并还原它。

–贾斯汀
2012年4月30日15:51

别客气。我认为删除数据目录的内容并执行initdb就足够了。

– Craig Efrein
2012年4月30日15:56



效果很好,我只建议跳过gzip部分以节省时间。

–拉斐尔·巴博萨(Rafael Barbosa)
16年11月4日在13:50

#2 楼

注意:我已经在9.1上对此进行了测试。我这里没有9.0服务器。我很确定,尽管它可以在9.0上使用。 br />
通过使用临时表空间,您几乎可以在不停机的情况下完成此操作。停机时间将以排他锁的形式出现。但是,只有在桌子上,您才在吸尘。因此,所有发生的事情就是,如果客户端查询访问有问题的表,它们将仅等待获取锁。您不需要关闭现有的连接。

但要注意的一件事是,移动桌子和将真空吸尘器本身首先需要等待排它锁!


首先,您显然需要一些额外的存储空间。正如Stéphane在评论中提到的那样,它的大小至少必须是VACUUM FULL完整副本的两倍。如果幸运的话,可以将磁盘动态添加到计算机,请执行此操作。在最坏的情况下,您可以仅连接USB磁盘(虽然速度较慢且速度慢)! />
您可以使用以下命令轻松列出表空间:到):

Note that high CPU load due to I/O operations may be expected.


如果是NULL,它将在默认表空间中:

CREATE TABLESPACE tempspace LOCATION '/path/to/new/folder';


如果也就是NULL,也可能是pg_default(如果已更改,请查看官方文档)。

现在将桌子移到上方:

\db


抽真空: >将其移回:

SELECT tablespace FROM pg_tables WHERE tablename = 'mytable';


删除临时空间:

SHOW default_tablespace;


评论


注意:此举似乎在原始数据目录中使用了更多的磁盘空间...

–克里斯·威瑟斯
15年11月24日在11:13

刚刚在9.3上进行了测试,它就像魅力一样工作。

– Bartek Jablonski
16年7月27日在6:10

在9.1上成功用于生产。更改表空间后,将释放原始使用的空间。请注意,可能会由于I / O操作而导致较高的CPU负载。

–erny
16年7月29日在19:06

惊人的提示,感谢您的详细说明。请注意,在临时表空间上,您至少需要表x 2的大小,因为VACUUM FULL正在制作表的完整副本。

–Stéphane
18 Mar 8 '18 at 14:27

谢谢@Stéphane。我将信息添加到主体中。

– exhuma
18 Mar 9 '18 at 8:40



#3 楼

快速又肮脏:


停止Postgres
将主数据库目录移动到另一个有足够空间进行清理的磁盘上
在main的原始位置中添加符号链接移至新位置
真空
删除符号链接并将主目录移回其原始位置
启动Postgres

例如::

$ service postgresql stop $ mv /var/lib/postgresql/9.5/main /mnt/bigdisk $ ln -sr /mnt/bigdisk/main /var/lib/postgresql/9.5 $ vacuumdb --all --full $ rm /var/lib/postgresql/9.5/main $ mv /mnt/bigdisk/main /var/lib/postgresql/9.5 $ service postgresql start

#4 楼

如果您有足够的磁盘空间来执行转储和还原,则应该有足够的磁盘空间来执行vacuumdb --full。问题在于vacuumdb --full将复制整个数据文件。因此,您可以执行以下操作:


将保存巨大表的文件复制到其他驱动器,例如,速度更慢,更大的驱动器。
从另一个驱动器上的原始位置到新位置建立符号链接。
运行vacuumdb --full,现在它应该从另一个磁盘读取数据,并将最终表写入原始数据磁盘。