Wie kann ich die Ursache für Postgresql-Speicherlecks pro Verbindung finden?

8

Ich verwende postgresql 9.5.4 auf Amazon RDS mit ~ 1300 dauerhaften Verbindungen von Rails 4.2 mit "prepare_statements: false". Im Laufe von Stunden und Tagen sinkt der RDS-Status "Freeable Memory" weiterhin auf unbestimmte Zeit, springt jedoch bei jeder erneuten Verbindung (Neustart unserer Server) auf einen relativ kleinen Arbeitssatz zurück. Wenn wir es zu lange laufen lassen, geht es bis auf Null und die Datenbankinstanz beginnt wirklich zu tauschen und schlägt schließlich fehl. Wenn wir den frei verfügbaren Speicher über Tage von den Spitzenwerten beim Neustart abziehen, sehen wir, dass durchschnittlich 10 MB pro Verbindung vorhanden sind.

Geben Sie hier die Bildbeschreibung ein

Wenn wir uns das Per-Pid-RSS aus der erweiterten Überwachung ansehen, sehen wir das gleiche langsame Wachstum bei Beispiel-Verbindungs-Pids, aber das gesamte RSS scheint nur ein Proxy für die tatsächliche Speichernutzung pro Verbindung zu sein ( https://www.depesz.com/2012/). 06/09 / wie viel RAM ist postgresql-using / ).

Geben Sie hier die Bildbeschreibung ein

Wie kann ich entweder:

  1. Ändern Sie die folgenden default.postgres9.5-Parameter, um ein unbegrenztes Speicherwachstum pro Verbindung zu vermeiden
  2. Bestimmen Sie, welche Abfragen dieses unbegrenzte Wachstum verursachen, und ändern Sie sie, um dies zu verhindern
  3. Bestimmen Sie, welche Art von Pufferung / Caching dieses unbegrenzte Wachstum verursacht, damit ich damit eines der oben genannten Schritte ausführen kann

Geben Sie hier die Bildbeschreibung ein

Eric Jensen
quelle

Antworten:

3

Wenn Sie Community PostgreSQL verwendet haben, besteht die endgültige Antwort darauf , herauszufinden, wo sich der Speicher unter Linux befindet, darin, eine Verbindung zu einem aufgeblähten Backend mit gdb herzustellen und p MemoryContextStats(TopMemoryContext)die Ausgabe aus der Server-Protokolldatei zu überprüfen. Da Sie jedoch keine Community-PostgreSQL verwenden, besteht die endgültige Antwort darin, sich an Ihren bezahlten Support zu wenden und ihn zu bitten, dies für Sie herauszufinden.

Die wahrscheinlichste Ursache dafür ist, dass PostgreSQL einen Cache mit Metadaten pro Verbindung über alle Datenbankobjekte (Tabellen, Indizes usw.) verwaltet, die es während der Verbindungslebensdauer berührt hat. Es gibt keine Obergrenze für die Größe dieses Caches und keinen Mechanismus zum Ablaufen. Wenn Sie also Hunderttausende oder Millionen dieser Dinge haben und eine langlebige Verbindung irgendwann jedes einzelne davon berührt, wächst ihre Speichernutzung kontinuierlich. Die übliche Lösung hierfür (vorausgesetzt, Sie können die Anzahl der Objekte in Ihrer Datenbank nicht reduzieren) besteht darin, Ihren Verbindungspooler so einzurichten, dass jede Verbindung eine maximale Lebensdauer hat, bevor sie geschlossen und nicht recycelt wird.

jjanes
quelle