Запрос для django_migrations все еще выполняется

Я разрабатываю веб-приложение django и заметил кое-что странное. Следующий запрос останется в БД.

ВЫБЕРИТЕ "django_migrations". "App", "django_migrations". "Name" ИЗ "django_migrations"

вот пример из: выберите query_start, state_change, ожидание, состояние, запрос из 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"

Текущие настройки:

  • Джанго 1.11.2
  • PostgreSQL 9.2.17
  • Только с использованием Django ORM
  • Все миграции были применены
  • CONN_MAX_AGE установлен в settings.py

Почему Django не закрывает соединение после выполнения запроса?


person Myth    schedule 21.06.2017    source источник
comment
Что вы имеете в виду, запрос все еще выполняется? Как вы это определяете? В первую очередь, как вы с этим справляетесь?   -  person Daniel Roseman    schedule 21.06.2017
comment
через pg_stat_activity. Запрос все еще находится в состоянии ожидания, и соединение все еще живо через 10/15 часов.   -  person Myth    schedule 21.06.2017


Ответы (1)


Из документации, Django использует постоянные соединения:

[...] каждый поток поддерживает свое собственное соединение

Команда runserver сама по себе является потоком, а SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations" просто представляет последний запрос, сделанный в соединении, после того как результаты были возвращены, состояние остается незанятым.

Если вы попытаетесь выполнить запрос после проверки миграции, например, в wsgi, этот запрос заменит тот, который вы видите.

Следовательно, сервер выполнения по умолчанию создает поток для каждого входящего запроса, поэтому соединение, установленное (в основном потоке) для проверки миграций, никогда не закрывается документом:

В начале каждого запроса Django закрывает соединение, если оно достигло максимального возраста. Если ваша база данных завершает незанятые соединения через некоторое время, вам следует установить для CONN_MAX_AGE более низкое значение, чтобы Django не пытался использовать соединение, которое было прервано сервером базы данных. (Эта проблема может затронуть только сайты с очень низким трафиком.)

Как вы можете прочитать, закрытие выполняется либо Postgres, либо Django по следующему запросу. Итак, вы либо настраиваете postgres для уничтожения незанятых соединений, либо вы можете использовать --nothreading на сервере выполнения для повторного использования соединения, созданного основным потоком (предупреждение: это сильно влияет на производительность).

person SebCorbin    schedule 21.06.2017
comment
Спасибо за ответ, но почему, если я установил для параметра «CONN_MAX_AGE» значение 5 секунд, соединение все равно будет открыто? - person Myth; 21.06.2017
comment
Я добавил часть и объяснение того, почему первое соединение сохраняется с сервером выполнения - person SebCorbin; 21.06.2017
comment
Спасибо за ответ, наверное, я неправильно понимаю, как работает CONN_MAX_AGE. Я, вероятно, буду использовать from django.db import close_old_connections close_old_connections() для управления автоматическим закрытием соединения с помощью автоматической задачи. Спасибо - person Myth; 22.06.2017