2017-06-26 1 views
0

Je ne mets pas la variable CONN_MAX_AGE dans ma config, on dit qu'elle sera 0 par défaut, ce qui signifie que chaque requête rouvrira une nouvelle connexion. Mais dans mon programme elle affiche continuellement l'erreur (2006, serveur parti) comme chaque requête commence. Je ne sais pas pourquoi.Il y a une erreur de 2006 (serveur parti) continuellement dans mon django, pourquoi est-ce?

+0

Vous devez être un peu plus précis. Est-ce lors du chargement d'une page dans une vue? Exécuter une commande de gestion? S'agit-il de toutes les vues, ou seulement de quelques-unes - téléchargez-vous des fichiers volumineux, par exemple? – Withnail

+0

Je cours mon programme dans le mode de commande, et mon programme durera environ 5hours, qui envoie continuellement la question à la DB.A la fin de mon programme, il signale continuellement l'erreur. Mais ma config est réglée comme ci-dessus. Je suis impatient de votre réponse. @Withnail –

Répondre

0

Vous n'êtes pas seul. Cela a été un problème connu depuis 1.6, et je crois reste. (Heureux d'être corrigé). Documentation d'origine relative au problème from the Django Project.

De façon générale, je reconfigurerais votre problème de sorte que vous ouvriez une nouvelle connexion de base de données périodiquement. Nous avons un certain nombre de processus de longue durée qui se connectent à MySQL et nous avons trouvé que c'était un problème récurrent.

Vous avez trois options.

Brisez légèrement votre fonction pour que les blocs puissent chacun établir leur propre connexion. Cela devrait être le comportement implicite de la configuration que vous avez décrite, mais j'ai aussi rencontré des problèmes avec cela.

de django importation db

for thing in some_data: 
    db.connections.close_all() 
    your_stuff_here() 

La fermeture explicite (et réouverture ultérieure) de la connexion est également plus clair que le comportement implicite, qui dépend aussi de la façon dont votre délai MySQL est configuré.

Une solution très hacky est d'envelopper vos fonctions internes dans un try/except:

from django.db.utils import OperationalError 
try: 
    stuff = Stuff.objects.get(id=123456) 
except OperationalError: 
    from django.db import connections 
    c = connections['default'].cursor() 
    stuff = Stuff.objects.get(id=123456) 

Cela fonctionne vraiment, comme la connexion du curseur, il rouvre en cas de défaillance. Bien que je l'ai implémenté comme une solution sur l'un de nos processus de longue durée, c'est définitivement un hack. Je ne le recommande pas, et nous l'avons refactorisé par la suite à la première méthode. Enfin, vous pouvez augmenter votre délai d'attente MySQL, qui est noté sur la page de documentation de django comme une solution moins optimale.

https://dev.mysql.com/doc/refman/5.6/en/auto-reconnect.html

+0

merci beaucoup, je pense que le CONN_MAX_AGE est inutile, je l'ai mis à des valeurs différentes, mais il reste la même connexion que je vois de la liste de processus mysql. –

+0

CONN_MAX_AGE est uniquement utilisé dans les requêtes HTTP où Django le gère à l'aide de signaux. Par conséquent, si vous exécutez une commande de gestion, vous devez appeler explicitement close_old_connections pour vérifier l'heure à laquelle elle doit être fermée. Corrige moi si je me trompe. –