真空/自动真空操作需要多少时间?


18

我管理着一个大型的数据库(数百个演出),其中包含具有各种角色的表,其中一些表拥有数百万条记录。一些表只接收大量的插入和删除,另一些表则接收大量的插入和删除。

数据库在带有16 GB RAM的Debian 6.0 amd64系统上的PostgreSQL 8.4上运行。

问题有时是在桌子上进行自动真空处理,需要很长时间(几天)才能完成。我希望能够粗略地知道一个特定的真空命令将花费多少时间,以便能够决定是否取消它。另外,如果有用于postgres真空操作的进度指示器,那将真的很有帮助。

编辑:

我不是在寻找防弹解决方案。只需给出死元组数或必要的I / O字节数的粗略提示就可以确定。VACUUM无论何时何地都不知道,真是令人讨厌。

我已经看到pg_catalog.pg_stat_all_tables有一个死元组数列。因此,即使有可能需要对表进行估算,也可以进行估算ANALYZE。在另一方面,autovacuum_vacuum_thresholdautovacuum_vacuum_scale_factor设置单独证明Postgres的本身知道一些有关变化对表的数量,并可能将其放在了DBA手中了。

我不确定要运行什么查询,因为在运行时VACUUM VERBOSE,我不仅看到表,而且也正在处理它们的索引。

Answers:


34

在我的PostgreSQL(8.3)上,我使用以下技巧:

  1. 我使用以下方法获取表的磁盘大小pg_total_relation_size()-这包括索引和TOAST大小,这是要VACUUM处理的内容。这使我想到VACUUM必须读取多少字节。
  2. VACUUM在桌子上跑。
  3. 我在中找到了pidVACUUM过程的pg_catalog.pg_stat_activity
  4. 在Linux Shell中,我运行while true; do cat /proc/123/io | grep read_bytes; sleep 60; done123PID 在哪里)-到目前为止,该过程向我显示了该进程从磁盘读取的字节。

这使我大致了解了每分钟要处理(读取)多少个字节VACUUM。我假设VACUUM必须读取整个表(包括索引和TOAST),我从步骤1中知道了它的磁盘大小。

我认为该表足够大,因此必须从磁盘读取它的大部分页面(它们在Postgres共享内存中不存在),因此该read_bytes字段足以用作进度计数器。

每次执行此操作时,该进程读取的总字节数都不超过总关系大小的5%,所以我想这种方法对您可能已经足够了。


讨厌的:)也可以在以后的版本中使用吗?而且,更重要的是,用于自动真空吗?
dezso

我还没有尝试过新版本。它应该VACUUM FULL在9.0+上工作,因为它完全重写了表。它也应该适用于常规VACUUM,但我尚未对其进行测试。对于autovacuum如果你能捉对给定表的自动清理工作进程,将工作,但我不知道如何实现这一目标。
罗曼·霍克

您对如何使用RDS实现这一目标有任何建议吗?自然,使用RDS时,我们无法访问linux shell,但我们也非常希望能够对此进行估算。
jwg2s

@ jwg2s请问“ RDS”是什么意思?亚马逊的数据库服务?如果是这样,我遗憾的是不熟悉它:-(也许他们的支持将有助于。
罗马Hocke

1
似乎在充满真空的PG 10上也能很好地工作。
DylanYoung '19

9

这很难确定。您可以调整自动真空度,使其更具攻击性更加温和。但是,当设置为“温和”并且滞后并且基本I / O负载过高时,可能会发生它永远不会达到适当的真空状态-然后您会看到进程正在运行,并且正在运行。此外,后期的PostreSQL版本具有大大改进的自动清理功能,仅此一项就足以迁移到其中一个(最好是9.2)。

进度条听起来是个好主意,但我想有意义地实现它并不容易。由于您的表上的负载恒定,因此很可能进度明显倒退了(我的意思是,死行计数/百分比增加而不是减少)-那么您得出什么结论呢?


2
我更喜欢看到某种进度指示器,即使它向后移动,也不是没有。
zaadeh

3
VACUUM ANALYZE VERBOSE至少会在控制台上显示一些活动。最好只是盯着一个静态提示,想知道是否有东西停留了几个小时。
假名称

该问题询问“真空/自动真空”。上面的内容仅对有用VACUUM,而对autovacuum无效,但仍然有用。
假名称

@FakeName嗯,我误解了问题-错过了手动吸尘器部分。抱歉,我要删除我的评论。
dezso

3

在我们的产品中,最大的表格之一具有以下日志:

pages: 0 removed, 1801722 remain
tuples: 238912 removed, 42582083 remain, 1396 are dead but not yet removable
buffer usage: 9477565 hits, 3834218 misses, 2220101 dirtied
avg read rate: 2.976 MB/s, avg write rate: 1.723 MB/s
system usage: CPU 68.47s/177.49u sec elapsed 10065.08 sec

到目前为止,这是最糟糕的资源消耗,所有其他表花费的时间不到2秒。

要查看这些类型的日志,您应该执行以下命令:

alter system set log_autovacuum_min_duration TO 5; 

(持续5毫秒),请重新加载配置文件。


3

我发现这个职位这个职位有帮助的,但像其他人所说的,它可以是难以计算真空的整体进展,因为该过程涉及几个独立的操作。

我使用此查询监视真空表扫描的进度,这似乎是大部分工作:

SELECT heap_blks_scanned/cast(heap_blks_total as numeric)*100 as heap_blks_percent, progress.*, activity.query
FROM pg_stat_progress_vacuum AS progress
INNER JOIN pg_stat_activity AS activity ON activity.pid = progress.pid;

但是,这将不包括索引扫描,索引扫描将在之后进行,如果您有大量的索引,则可能花费的时间甚至更长。不幸的是,我找不到监视索引扫描/清理的方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.