3

我正在开发一个 django 网络应用程序,我注意到一些奇怪的事情。以下查询将在数据库中继续执行

从“django_migrations”中选择“django_migrations”。“app”,“django_migrations”。“名称”

这里的例子来自:select query_start,state_change,waiting,state,query from 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"

直到停止“运行服务器”

当前的设置:

  • Django 1.11.2
  • PostgreSQL 9.2.17
  • 仅使用 Django ORM
  • 已应用所有迁移
  • 在 settings.py 中设置的 CONN_MAX_AGE

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

4

1 回答 1

4

文档中,Django 使用持久连接:

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

The runserver command is itself a thread, and the SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations" simply represent the last query made on the connection, once the results has been returned, the state is left idle.

If you try to execute a query once migrations are checked, in wsgi for example, that request would replace the one you are seeing.

Hence, the runserver by default create a thread for each incoming request, so the connection made (in main thread) for checking migrations is never closed, by the doc:

At the beginning of each request, Django closes the connection if it has reached its maximum age. If your database terminates idle connections after some time, you should set CONN_MAX_AGE to a lower value, so that Django doesn’t attempt to use a connection that has been terminated by the database server. (This problem may only affect very low traffic sites.)

As you can read, the closing is made either by Postgres, or by Django on the next request. So either you configure postgres to kill the idle connections, or you can use the --nothreading on runserver to reuse the connection made by the main thread (warning: it highly affects performance).

于 2017-06-21T14:10:18.773 回答