2017-06-21 210 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