我正在尝试测量生活在同一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文档说活动意味着
后端正在执行查询。
和空闲意味着
后端正在等待新的客户端命令。
它真的比那更微妙吗?当我签入时,为什么运行我的查询的流程不是活动?
如果这种方法存在缺陷,那么在数据库粒度上测量负载的方法有哪些,而不是定期采样活动进程的数量?
答案 0 :(得分:0)
您对active
,idle
和idle in transaction
的期望是非常正确的。我能想到的唯一解释是显示数据客户端方面的巨大延迟。所以查询确实在服务器和会话上完成了idle
,但你没有看到客户端的结果。
关于负载测量 - 我不会太依赖于活动会话的数量。在运行状态下点击快速查询的纯粹运气。例如,假设您可以每秒检查pg_stat_activity
并查看一个活动会话,但在测量之间,一个数据库被查询10次而另一个被查询一次 - 但这些数字都不会被看到。因为它们在执行之间是活跃的。而这10 + 1个活动状态(虽然意味着一个数据库被查询的次数多10次)并不意味着你应该考虑加载 - 因为集群没有被加载,你甚至无法捕获执行。但这不可避免地意味着您可以捕获许多活动会话,但这并不意味着服务器确实已加载。
所以至少将now()-query_start
带到查询中以捕获更长的查询。或者甚至更好地节省一些常常查询的执行时间,并测量它是否随着时间的推移而降级。或者更好地选择pid
并检查该pid所吃的资源。
对于更长时间的查询,请查看pg_stat_statements - 查看它们如何随时间变化可以给出一些关于负载变化的预期