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

zaa*_*deh 27 postgresql vacuum

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

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

问题有时是桌子上的 autovacuum 过程,需要很长时间(几天)才能完成。我希望能够粗略地判断一个特定的vacuum 命令需要多长时间,以便能够决定是否取消它。此外,如果有 postgres 真空操作的进度指示器,那将非常有帮助。

编辑:

我不是在寻找防弹解决方案。对死元组的数量或必要的 I/O 字节数的粗略提示就足以决定。不知道什么时候VACUUM结束真的很烦人,无论如何。

我已经看到pg_catalog.pg_stat_all_tables有一个列表示死元组的数量。所以有可能有一个估计,即使这意味着一个人必须ANALYZE在之前的桌子上。在另一方面,autovacuum_vacuum_thresholdautovacuum_vacuum_scale_factor设置单独证明Postgres的本身知道一些有关变化对表的数量,并可能将其放在了DBA手中了。

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

小智 45

在我的 PostgreSQL (8.3) 上,我使用了这个技巧:

  1. 我使用表的磁盘大小pg_total_relation_size()- 这包括索引和 TOAST 大小,这就是VACUUM进程。这让我知道VACUUM必须读取多少字节。
  2. VACUUM在桌子上跑。
  3. 我找到pid的的VACUUM过程(中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%,所以我想这种方法可能对你来说已经足够了。

  • 从 PostgreSQL 9.6 开始,您可以使用 pg_stat_progress_vacuum 表来清除进度信息 (5认同)
  • 讨厌:) 这也适用于更高版本吗?更重要的是,对于自动真空? (2认同)
  • 似乎在真空充满的 PG 10 上也能很好地工作。 (2认同)
  • 我尝试在 Postgres 9.5 上使用这种技术来估计我的“VACCUM ANALYZE VERBOSE bigtable”,它现在已经运行了 5.5 小时。我在 pg_total_relation_size() 中看到的 bigtable 是 718GB,但是`虽然是真的;做 cat /proc/123/io | grep read_bytes; sleep 60;` VACCUM pid 显示到目前为止已读取 2256301645824 个字节(超过 2TB!)。我错过了什么?我如何估计这个长时间运行的“VACCUM”的剩余时间? (2认同)
  • 要将其作为百分比,您可以运行 `while true; 做 echo "$(sudo cat /proc/1234/io | grep read_bytes | tr -dc '0-9') * 100 / 50000000" | 公元前; 睡30;done` 其中 `50000000` 是字节数形式 `SELECT pg_total_relation_size('table_name');` (2认同)

Cer*_*rin 10

我发现这篇文章这篇文章很有帮助,但就像其他人提到的那样,计算真空的整体进度可能很困难,因为该过程涉及一些单独的操作。

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

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;
Run Code Online (Sandbox Code Playgroud)

但是,这不包括索引扫描,后者发生在之后,并且如果您有大量索引,则可能需要同样长的时间,甚至更长的时间。不幸的是,我找不到监控索引扫描/清理的方法。


dez*_*zso 9

这很难确定。您可以将自动清扫调整为更具侵略性或更温和。但是当设置为温和并且它滞后并且基本 I/O 负载太高时,可能会发生它永远不会达到适当的真空状态 - 然后您会看到进程正在运行,运行和运行。此外,后来的 PostreSQL 版本大大改进了 autovacuum 功能,仅这一点就足以转移到其中之一(最好是 9.2 作为最新版本)。

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

  • `VACUUM ANALYZE VERBOSE` 至少会在控制台上打印一些活动。最好只是盯着一个静态提示,想知道是否有什么东西卡住了几个小时。 (3认同)
  • 我更喜欢看到某种进度指示器,即使它倒退,而不是什么都不做。 (2认同)

小智 5

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

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
Run Code Online (Sandbox Code Playgroud)

这是迄今为止最严重的资源消耗,所有其他表都花费了不到 2 秒。

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

alter system set log_autovacuum_min_duration TO 5; 
Run Code Online (Sandbox Code Playgroud)

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