2017-06-21 49 views
3

我正在开发一个Django的Web应用程序,我发现有些奇怪的东西。 下面的查询将留在执行中DB查询仍在运行django_migrations

SELECT “django_migrations”, “应用”, “django_migrations”, “名” FROM “django_migrations”

这里的例子来自:选择query_start ,state_change,waiting,state,来自pg_stat_activity的查询;

test6=> select query_start,state_change,waiting,state,query from pg_stat_activity; 
      query_start   |   state_change   | waiting | state |                 query 
-------------------------------+-------------------------------+---------+--------+-------------------------------------------------------------------------------------------------- 
2017-06-21 16:02:21.926337+02 | 2017-06-21 16:02:21.926402+02 | f  | idle | SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations" 

,直到停止 “的runserver”

当前设置:

  • 的Django 1.11.2
  • 的PostgreSQL 9.2.17
  • 使用Django ORM仅
  • 所有移民都应用
  • CONN_MAX_AG E set in settings.py

为什么Django在查询执行后没有关闭连接?

+0

你是什么意思,查询仍在运行?你如何确定?你最初如何运行它? –

+0

通过“pg_stat_activity”。查询仍处于“空闲”状态,并且连接在10/15小时后仍处于活动状态。 – Mattia

回答

3

documentation,Django使用持久连接:

[...]每个线程维护其自己的连接

runserver命令本身就是一个线程,和SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"简单地表示在连接上进行的最后一次查询,一旦结果返回,状态就保持空闲状态。

如果您在尝试迁移时尝试执行查询,例如在wsgi中,该请求会替换您正在查看的那个。

因此,通过默认的runserver创建为每个传入请求的线程,因此由用于检查迁移的连接(在主线程)永远不会关闭,由DOC:

在开始时每个请求,Django关闭连接,如果它 已达到其最大年龄。如果您的数据库在一段时间后终止空闲 连接,则应将CONN_MAX_AGE设置为较低的值 ,以便Django不会尝试使用数据库服务器已终止 的连接。 (这个问题可能只会影响 非常低流量的网站。)

正如您可以阅读,收盘是将所Postgres的,或由Django的下一个请求。因此,要么配置postgres来终止空闲连接,要么您可以使用runserver上的--nothreading来重新使用主线程所做的连接(警告:它会严重影响性能)。

+0

感谢您的回复,但为什么如果我将'CONN_MAX_AGE'设置为5秒,连接仍然打开? – Mattia

+0

我添加了部分和解释,为什么第一次连接保持runserver – SebCorbin

+0

感谢您的回复,我可能误解了CONN_MAX_AGE的工作原理。我可能会使用'from django.db import close_old_connections close_old_connections()'来管理自动关闭与自动任务的连接。谢谢 – Mattia