跟踪 Python 和 PostgreSQL 的数据库连接问题
Tracking out of database connection issues with Python and PostgreSQL
我定期遇到与 PostgreSQL 的连接问题 - "FATAL: remaining connection slots are reserved for non-replication superuser connections" 或 "QueuePool limit of size 5 overflow 10 reached, connection timed out, timeout 30" 取决于 psycopg 或 Pyramid 是否引发异常。确定事务管理器已正确安装后,令人沮丧的是不知道为什么我仍然 运行 没有连接。
我知道连接数据在 pg_stat_activity 中,但它是单个快照。有什么方法可以随着时间的推移查看连接,以便我可以看到一段时间内实际 运行 是什么(理想情况下是从问题出现之前到问题需要重新启动应用程序为止)?
第一部分是正确识别某个时间点的所有查询 运行。为此,我使用了这个查询:
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();
注意! "current_query" 在 postgresql 的更高版本(从 9.2 开始)中简称为 "query"
这会删除所有空闲的数据库连接(查看空闲连接不会帮助您修复它)并且 "NOT procpid=pg_backend_pid()" 位会排除此查询本身出现在结果中(这会使您的输出显着膨胀).如果要隔离特定数据库,还可以按 datname 进行过滤。
我需要以一种非常容易查询的方式获得这些结果,因此我在数据库上使用了 table。这应该有效:
创建 TABLE connection_audit
(
没有时区的快照时间戳 NOT NULL DEFAULT now(),
total_connections 整数,
idle_connections 整数,
查询文本
)
和 (
OIDS=假
);
这将在 "snapshot" 中存储当前时间戳、总连接数和空闲连接数以及查询本身。
我编写了一个脚本,将顶部查询插入 table 并将其保存到名为 "pg_connections.sql" 的文件中。
我 运行 脚本每秒将这些结果插入 table:
while true ; do psql -U user -d database_name -f 'pg_connections.sql' >> connections.log ; sleep 1; done
这实际上是将所有当前正在执行的查询写入 table。
拖尾 connections.log 文件告诉我脚本是否如预期的那样 运行(但这并不是真正需要的)。显然,每秒 运行 这样的脚本可能会对系统造成负担,但如果您没有任何其他方法可以找到此信息,那么这是一种短期措施,所以它应该是值得的。 运行 这个脚本只要你需要积累足够的数据,希望它能付诸实践。
我定期遇到与 PostgreSQL 的连接问题 - "FATAL: remaining connection slots are reserved for non-replication superuser connections" 或 "QueuePool limit of size 5 overflow 10 reached, connection timed out, timeout 30" 取决于 psycopg 或 Pyramid 是否引发异常。确定事务管理器已正确安装后,令人沮丧的是不知道为什么我仍然 运行 没有连接。
我知道连接数据在 pg_stat_activity 中,但它是单个快照。有什么方法可以随着时间的推移查看连接,以便我可以看到一段时间内实际 运行 是什么(理想情况下是从问题出现之前到问题需要重新启动应用程序为止)?
第一部分是正确识别某个时间点的所有查询 运行。为此,我使用了这个查询:
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();
注意! "current_query" 在 postgresql 的更高版本(从 9.2 开始)中简称为 "query"
这会删除所有空闲的数据库连接(查看空闲连接不会帮助您修复它)并且 "NOT procpid=pg_backend_pid()" 位会排除此查询本身出现在结果中(这会使您的输出显着膨胀).如果要隔离特定数据库,还可以按 datname 进行过滤。
我需要以一种非常容易查询的方式获得这些结果,因此我在数据库上使用了 table。这应该有效: 创建 TABLE connection_audit ( 没有时区的快照时间戳 NOT NULL DEFAULT now(), total_connections 整数, idle_connections 整数, 查询文本 ) 和 ( OIDS=假 );
这将在 "snapshot" 中存储当前时间戳、总连接数和空闲连接数以及查询本身。
我编写了一个脚本,将顶部查询插入 table 并将其保存到名为 "pg_connections.sql" 的文件中。
我 运行 脚本每秒将这些结果插入 table:
while true ; do psql -U user -d database_name -f 'pg_connections.sql' >> connections.log ; sleep 1; done
这实际上是将所有当前正在执行的查询写入 table。
拖尾 connections.log 文件告诉我脚本是否如预期的那样 运行(但这并不是真正需要的)。显然,每秒 运行 这样的脚本可能会对系统造成负担,但如果您没有任何其他方法可以找到此信息,那么这是一种短期措施,所以它应该是值得的。 运行 这个脚本只要你需要积累足够的数据,希望它能付诸实践。