Django ORM在Postgres DB上保留空闲连接

Django ORM在Postgres DB上保留空闲连接,django,postgresql,database-connection,django-orm,Django,Postgresql,Database Connection,Django Orm,最近,由于数据库连接错误,my Django应用程序频繁崩溃: OperationalError: FATAL: sorry, too many clients already 当我进入应用程序数据库时,我看到确实有近100个打开的连接,它们都使用相同的查询(由Django ORM执行),并且都处于idle状态 我一直在手动执行从pg_stat_活动中选择pg_terminate_后端(pid),其中state='idle'

最近,由于数据库连接错误,my Django应用程序频繁崩溃:

OperationalError: FATAL:  sorry, too many clients already
当我进入应用程序数据库时,我看到确实有近100个打开的连接,它们都使用相同的查询(由Django ORM执行),并且都处于
idle
状态

我一直在手动执行
从pg_stat_活动中选择pg_terminate_后端(pid),其中state='idle'
我的Django数据库设置没有偏离默认设置(我没有定义
CONN_MAX_AGE
或任何类似的属性)


这是什么原因造成的?我没有做任何高级Django查询。这是否可以通过Django设置或某些PostgreSQL配置来解决?任何建议都非常感谢。

没有更多细节的最佳猜测,但是如果是同一个查询,并且它们都是空闲的,那么感觉就像是在进行某种异步编程,并且遇到了死锁,特别是在数据库连接饱和的情况下,死锁正在显现出来。

显然,您没有断开连接。查询完成后使用
db.close\u connection()
会有所帮助。另外,如果我把它做对的话,
CONN\u MAX\u AGE
一些短值可能会有所帮助。考虑使用一些会话池,例如Django连接的PGBONCER。这样,如果您有太多的连接,它将等待(或重用以前的连接,具体取决于配置),而不是在出现错误时中止执行

更新:解释我提出该建议的原因

每个线程都维护自己的连接,数据库必须支持 至少与工作线程的同时连接数相同


因此,如果您有比postgres
max_connections
更多的线程,那么您会遇到提到的错误。如果未超过CONN_MAX_年龄,则每个线程都可以重用连接。您的设置为0,所以在查询完成后应该关闭连接,但您会看到100个空闲连接。所以他们没有关门。大量的连接意味着它们也不会被重用(逻辑:如果你有100个并行查询,它们不会都是空闲的,如果你有这么多,它们也不会被重用——打开新的)。所以我认为django并没有像承诺的那样关闭它们——所以CONN_MAX_AGE设置为0在您的代码中不起作用。因此,我建议使用
db.close\u connection()
强制断开连接,并将CONN\u MAX\u AGE设置为某个较小的值可以改变行为。

如果您没有定义
CONN\u MAX\u AGE
并且没有使用任何第三方池,那么这一定是您的代码或正在使用的库中的某个问题。默认情况下,Django会根据请求打开和关闭数据库连接。在
pg_stat_activity
中看到空闲连接的事实并不意味着存在死锁-相反,它意味着某些东西打开了这些连接,而没有关闭它们


我首先要确定这些连接是否真的来自Django,比如重启应用程序,看看它对
pg\u stat\u活动的影响。如果您确认了这一点,那么请检查您是否混合了任何异步或多处理代码,从而导致线程/进程悬而未决。

尝试将其放到django IRC通道中,您使用的是哪个django版本?@raiderrobert on django 1.10.5我知道了,谢谢您的提示。我将研究如何检测死锁,看看这里是否发生了这种情况。我在应用程序中遇到了同样的问题。我尝试将多线程方法改为非多线程方法,解决了问题。因此,我正在寻找以异步方式(Postgresql db)插入/更新db记录的方法。@glifchits,你有什么发现或好的解决方案吗?我理解连接池的想法,但这个应用程序还没有达到需要引入第三方库来优化数据库使用的规模。我也不喜欢超越Django管理查询的功能(即手动调用
db.close\u connection()
)的想法。关于
CONN\u MAX\u AGE
:您知道是否有特定原因需要将该值设置为非默认值,为什么它可能是这种情况下的解决方案?我编辑了解释,为什么我认为CONN_MAX_AGE to small value会有所帮助。顺便说一句,连接池从1.9开始工作-你有更高的版本吗?