使用 pg_stat_activity 中的'active'进程测量 Postgres 中每个数据库的负载?



我正在尝试测量生活在同一Postgres服务器上的各种数据库所产生的负载,以确定如何在多个服务器上最好地拆分它们。我设计了这个查询:

select
now() as now,
datname as database,
usename as user,
count(*) as processes
from pg_stat_activity
where state = 'active'
and waiting = 'f'
and query not like '%from pg_stat_activity%'
group by
datname,
usename;

但令人惊讶的是,活跃的进程很少!

根据我运行它的客户的说法,我运行了一个简单的查询,返回了20k行,耗时5秒。在此期间,当我查询pg_stat_activity时,进程处于空闲状态!我把这个实验重复了好几次。

Postgres文档称active表示

后端正在执行查询。

空闲表示

后端正在等待新的客户端命令。

它真的比这更微妙吗?为什么当我签入时,运行我的查询的进程没有活动

如果这种方法有缺陷,那么除了定期对活动进程的数量进行采样之外,还有什么其他方法可以在数据库粒度上测量负载呢?

您对activeidleidle in transaction的期望非常正确。我能想到的唯一解释是显示数据客户端的巨大延迟。因此,查询确实在服务器和会话上完成了idle,但您没有看到客户端的结果。

关于负载测量-我不会太依赖活动会话的数量。在活动状态下快速查询纯属运气。例如,假设你可以每秒检查pg_stat_activity,并看到一个活动会话,但在测量之间,一个数据库被查询了10次,另一个数据库则被查询了一次,但这些数字都不会被看到。因为他们在两次处决之间都很活跃。这种10+1的活动状态(尽管意味着一个数据库被查询的频率要高出10次)并不意味着您应该考虑负载——因为集群中有太多未加载的内容,以至于您甚至无法捕获执行。但这不可避免地意味着您可以捕获许多活动会话,这并不意味着服务器确实已加载。

因此,至少将now()-query_start带到您的查询中,以捕获更长的查询。或者更好地为一些经常查询节省执行时间,并衡量它是否会随着时间的推移而降级。或者最好选择pid并检查该pid占用的资源。

顺便说一句,对于较长的查询,请查看pg_stat_statements-查看它们如何随时间变化可以让您对负载如何改变有一些期望

最新更新