PostgreSQL 长时间 VACUUM

4

我目前正在清理一张有两个索引、2.5亿活跃行和大约同样数量的死行(或更多)的表。我从我的客户端电脑(笔记本电脑)向服务器发出了VACUUM FULL ANALYSE命令。它已经在处理这个任务了大约3-4天左右,我想知道它是否会很快结束,因为我还有很多工作要做!

该服务器配备四核Xeon 2.66 GHz处理器、12 GB内存和一个连接到2个10K rpm 146 GB SAS硬盘的RAID控制器,以RAID 1配置运行Suse Linux操作系统。我在想...

首先,VACUUM后台进程似乎只使用了一个核心。其次,我没有看到非常高的I/O写入与I/O空闲时间比率。第三,通过调用procinfo,我可以推断出VACUUM进程大部分时间(88%)都在等待I/O。

那么为什么它不通过线程利用更多的核心来过载RAID控制器(获得高I/O写入空闲比)?如果I/O负载不高,为什么它要等待I/O?为什么它没有利用所有这些强大的资源来加快速度?在我看来,特别是当它正在处理一个巨大的表格并且它是唯一在工作的时候,VACUUM可以和应该是多线程的。

另外,有没有办法在postgresql.conf中配置它以使其多线程执行这样的VACUUM操作?我可以杀掉它,仍然从它的部分清理中受益吗?我需要在那张表上工作。

[我使用的是PostgreSQL 8.1]

再次感谢

4个回答

5

请问您使用的是哪个版本的PostgreSQL?是否是8.0之前的版本?

我曾经遇到过类似的情况。最好的解决方法如下:

  • 停止执行vacuum操作
  • 使用pg_dump -t选项备份表格数据
  • 删除表格
  • 恢复表格数据

如果您使用的是8.x版本,请参考自动垃圾回收选项。Vacuum是单线程的,无法使用多线程处理。


你说要杀掉VACUUM,然后回档表格,那么VACUUM的死亡会带来什么结果?我喜欢你的放弃和恢复的想法。谢谢 - Nicholas Leonard
3
当清空进程被终止时不会发生任何问题,只是你失去了到目前为止回收表空间所做的工作。我们有一个任务会在早上8点自动终止任何清空进程,这样用户在使用时就不会受阻。如果发生这种情况,我们会在第二天晚上进行数据库备份和恢复。 - Mark Harrison
1
从现在开始设置一个cron job来进行vacuuming可能是个好主意。 - Calyth
使用集群而不是完整的清空是否更好? - PKHunter

4

一些快速提示:

  • 运行VACUUM FULL VERBOSE,这样您就可以看到正在发生什么。
  • 在VACUUM之前删除所有索引。重建它们比清理它们要快。您还需要定期重建它们,因为VACUUM FULL不够好(特别是在如此古老的PosgreSQL 8.1上)。
  • 将maintenance_work_mem设置得非常高。
  • 使用更新的PostgreSQL版本。顺便说一句,8.4版本在清理方面有很大的改进。

VACUUM的替代方法是转储和恢复。

编辑:自从9.0版本以来,VACUUM FULL会重写整个表。这基本上与执行转储+恢复相同,因此运行REINDEX是不必要的。


0
你确定没有任何正在进行的操作会锁定表格并阻止VACUUM运行吗?
(无论如何,最好使用vacuum_cost_delay,以使VACUUM对生产不产生影响。)

0

旧的VACUUM FULL已经过时了。它也非常缓慢,而且之后还需要REINDEX。不要使用它。如果你真的想要对表进行碎片整理,请使用CLUSTER或者这个:

假设你还有一些磁盘空间,那么这比dump&reload快得多:

CREATE TABLE newtable AS SELECT * FROM oldtable;
CREATE INDEX bla ON newtable( ... );
ALTER TABLE oldtable RENAME TO archive;
ALTER TABLE newtable RENAME TO oldtable;

请注意,这不会复制您的约束条件。您可以使用 CREATE TABLE LIKE ... 来复制它们。

那么为什么它不能通过线程利用更多的核心呢?

pg 不支持此功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接