Wir haben eine ziemlich typische Django-App, die auf postgresql 9.0 läuft. Wir haben kürzlich einige Datenbankabfragen entdeckt, die wegen ineffizienter Suchen in der Admin-Oberfläche über 4 Stunden lang ausgeführt wurden. Während wir vorhaben, diese Abfragen zu reparieren, möchten wir die Datenbankabfragezeit als Sicherheitsmaßnahme künstlich auf 15 Sekunden beschränken - allerdings nur im Kontext einer Webanfrage. Batch-Jobs und Sellerie-Aufgaben sollten nicht durch diese Einschränkung begrenzt werden.
Wie können wir das machen? Oder ist es eine schreckliche Idee?
Dies wäre am besten, wenn Sie eine Rolle / einen Benutzer einrichten, der nur für die Ausführung der Webanforderungen verwendet wird, und dann das statement_timeout für diese Rolle festlegen.
%Vor%Alle anderen Rollen verwenden die globale Einstellung von statement_timeout (die in einer Aktieninstallation deaktiviert ist).
Sie müssen das manuell behandeln. Das überprüft die 15-Sekunden-Regel und löscht die Abfragen, die sie verletzen.
Frage pg_stat_activity ab, finde die Verletzer und erteile Aufrufe an pg_terminate_backend (procpid), um die Täter zu töten.
So etwas in einer Schleife:
%Vor%Was das Timing betrifft, können Sie alle Ihre Abfragen durch eine Klasse übergeben, die bei der Instanziierung zwei Threads erzeugt: einen für die Abfrage und einen für einen Timer. Wenn der Timer 15 Sekunden erreicht, dann töte den Thread mit der Abfrage.
Soweit herauszufinden, ob die Abfrage von einer Web-Anfrage instanziiert wird, weiß ich nicht genug über Django, um Ihnen zu helfen. Vereinfachend würde ich sagen, in Ihrer Klasse, die Ihre Datenbankaufrufe behandelt, könnte ein optionaler Parameter für den Konstruktor etwas wie context
sein, was http
im Falle einer Webanfrage und ""
für alles andere sein könnte.
Tags und Links django postgresql performance