我们正在使用 Django 1.3.1 和 Postgres 9.1
我有一个视图,它只是触发多个选择以从数据库中获取数据。
在 Django 文档中提到,当请求完成时,如果在调用视图期间仅触发了 select 语句,则会发出 ROLLBACK。但是,我在日志中看到很多“事务中的空闲”,尤其是当我有超过 200 个请求时。我在 postgres 日志中看不到任何提交或回滚语句。
可能是什么问题呢?我应该如何处理这个问题?
我们正在使用 Django 1.3.1 和 Postgres 9.1
我有一个视图,它只是触发多个选择以从数据库中获取数据。
在 Django 文档中提到,当请求完成时,如果在调用视图期间仅触发了 select 语句,则会发出 ROLLBACK。但是,我在日志中看到很多“事务中的空闲”,尤其是当我有超过 200 个请求时。我在 postgres 日志中看不到任何提交或回滚语句。
可能是什么问题呢?我应该如何处理这个问题?
首先,我会查看相关的帖子当 PostgreSQL 进程“处于事务中空闲”时是什么意思?这涵盖了一些相关的领域。
“Idle in transaction”的原因之一可能是输入“BEGIN”的开发人员或系统管理员;在 psql 中忘记“提交”或“回滚”。我去过那儿。:)
但是,您提到您的问题与有很多并发连接有关。听起来调查上面帖子中的“锁”提示可能对您有所帮助。
还有一些建议:这个问题可能是次要的。主要问题可能是 200 个连接超出了您的硬件和调整可以轻松处理的范围,所以一切都会变慢,当事情变慢时,更多的事情正在等待其他事情完成。
如果您的 Web 应用程序前面没有像 Nginx 这样的反向代理,请考虑添加一个。它可以在同一主机上运行而无需额外的硬件。反向代理将用于调节与后端 Django Web 服务器的连接数量,从而调节数据库连接的数量——我之前遇到过太多的数据库连接,这就是我解决它的方法!
使用 Apache 的 prefork 模型,假设使用 Apache::DBI 之类的东西,Apache worker 的数量和数据库连接的数量之间存在 1=1 的对应关系。想象一下有人通过慢速连接连接到 Web 服务器。Web 和数据库服务器相对较快地处理请求,但是只要内容被运回客户端,请求就会在 Web 服务器上保持打开状态,这是不必要的。同时,数据库连接槽被占用。
通过添加反向代理,后端服务器可以快速将回复传递回反向代理,然后释放后端工作人员和数据库槽。然后反向代理负责将内容返回给客户端,可能保持自己的开放状态连接时间更长。前面可能有 200 个到反向代理的连接,但后端需要的工作人员和数据库插槽要少得多。
如果您使用 MRTG 或类似工具绘制 db 插槽,您将看到您实际使用了多少插槽,并且可以调低 PostgreSQL 中的 max_connections,将这些资源释放用于其他用途。
您还可以查看pg_top以帮助监控您的数据库在做什么。
我知道这是一个较老的问题,但这篇文章可能会描述django 中的空闲事务问题。
本质上,如果事务没有被标记为脏(通常由写入数据触发),Django 的 TransactionMiddleware 不会显式地提交事务。然而,即使它们是只读的,它仍然为所有查询开始一个事务。因此, pg 等待查看是否有更多命令即将到来并且您获得空闲事务。
链接的文章显示了对事务中间件的小修改以始终提交(基本上删除了检查事务是否为脏的条件)。我将很快在生产环境中尝试此修复程序。