使用Python和PostgreSQL跟踪数据库连接问题

时间:2015-08-03 09:59:59

标签: python postgresql connection-pooling pyramid

我定期向PostgreSQL发出连接问题 - “FATAL:剩余连接插槽是为非复制超级用户连接保留的”或“QueuePool达到大小5溢出限制10,连接超时,超时30”取决于是否psycopg或金字塔正在提高例外。确定事务管理器已正确安装后,不知道为什么我仍然没有连接,这是令人沮丧的。

我知道连接数据在pg_stat_activity中,但它只是一个快照。有没有办法随着时间的推移看到连接,以便我可以看到一段时间内实际运行的内容(理想情况是从问题发生之前直到问题需要重新启动应用程序)?

1 个答案:

答案 0 :(得分:3)

第一部分是正确识别在某个时间点运行的所有查询。为此,我使用了这个查询:

SELECT (SELECT COUNT(1) FROM pg_stat_activity) AS total_connections,
    (SELECT COUNT(1) FROM pg_stat_activity
     WHERE current_query in ('<IDLE>', '<IDLE> in transaction'))
       AS idle_connections,
    current_query
FROM pg_stat_activity
WHERE current_query NOT IN ('<IDLE>', '<IDLE> in transaction')
    AND NOT procpid=pg_backend_pid();

注意! &#34; current_query&#34;简单地称为&#34;查询&#34;在postgresql的更高版本中(从9.2开始)

这剥离了所有空闲的数据库连接(看到IDLE连接不能帮助你修复它)和&#34; NOT procpid = pg_backend_pid()&#34; bit将此查询本身排除在结果中显示(这会大大增加您的输出)。如果要隔离特定数据库,也可以通过 datname 进行过滤。

我以一种非常容易查询它们的方式需要这些结果,所以我在数据库上使用了一个表。这应该工作: CREATE TABLE connection_audit (   没有时区的快照时间戳NOT NULL DEFAULT now(),   total_connections整数,   idle_connections整数,   查询文本 ) WITH(   OIDS = FALSE );

这会将当前时间戳存储在&#34; snapshot&#34;,总连接和空闲连接以及查询本身。

我编写了一个脚本,将顶层查询插入表中并将其保存到名为&#34; pg_connections.sql&#34;的文件中。

我运行了一个脚本,每秒都将这些结果插入到表中:

while true ; do psql -U user -d database_name -f 'pg_connections.sql' >> connections.log ; sleep 1; done

这有效的做法是将所有当前正在执行的查询写入表中。

tailing connections.log文件向我展示了脚本是否按预期运行(但并非真的需要)。显然,每秒运行一个这样的脚本可能会对系统造成负担,但当你没有任何其他方式来查找这些信息时,这是一个短期措施,所以它应该是值得的。只要你需要积累足够的数据就可以运行这个脚本,希望它能够付出代价。