psql verursacht 'out of memory killed process'

Hallo,

ich hab da ein seltsames Problem. Vor einigen Stunden machte ich die letzte Abfrage mit psql die funktionierte und seitdem suche ich nach einer Lösung, leider erfolglos. Jetzt saugt psql bei einer großen Ergebnismenge allen Speicher auf und wird letztendlich vom Kernel gekillt, bevor das Ergebnis angezeigt wird.

Datenbankabfragen mit meiner eigenen Software laufen ganz normal auch bei großen Ergebnismenge.

Hat vielleicht jemand eine Idee, welche Einstellung ich da vielleicht durcheinandergebracht habe?

Grüße
Alexander

Du hast natürlich nichts geändert, oder?

Nun, Wird niemand helfen können, wenn du nicht einige Begleitumstände und Einzelheiten des Problems schilderst.

Wie Du schon geschrieben hast, mir ist zumindest nicht bewust dass ich was geändert hätte. Deshalb habe ich auch nichts angegeben. Was ich zu der Zeit versuchte war Produktdaten aus der Datenbank zu selektieren und dazu verwendete ich eine externe SQL-Datei die ich mit dem Befehl \i ausführte. Zum Teil aber auch an der Kommandozeile eingegebene SQLs. Meine Vermutung war dass ich vielleicht mit einem dieser Befehle irgendetwas umgeschaltet habe das ihn veranlasst jetzt immer alle Zeilen eines ergebnisses laden zu wollen

Wilde Vermutung: CROSS-Join mit vielen, vielen Daten. Aber wir können halt wirklich nur vermuten…

Andreas

Tut mir ja leid aber ich weiss selbst nicht mehr. Es liegt sicher nicht an den Abfragen die liefen ja vorher auch.

z.B.:

select * from ProductKey;

Dieser ‘select’ lief bisher immer ohne Probleme. Trotz der aktuell 2,7 Mio. Datensätze in der Tabelle. Das waren schon mehr und es funktionierte trotzdem.

Gruß
Alexander

So, du holst also 2,7 Millionen Datensätze aus der Datenbank und psql soll diese darstellen. Schön, sollte funktionieren.

Steht irgendetwas im Logfile? Im System Log? Im Datenbank Log?

Hast du mal mit ulimit gespielt, um den Speicherverbrauch einzuschränken, bevor psql vom System gekillt werden muss?

Im syslog steht nur der kill vom Kernel. Die Datenbank logt bei mir ebenfalls im syslog und hüllt sich in Schweigen.

Ich ging eigentlich davon aus bei dem genannten ‘select’ werden nicht alle Daten zum Client übertragen sondern ein Teil und der Rest bei Bedarf nachgelesen. Wäre ja bei einer Verbindung übers Netz nicht wirklich sinnvoll alles zu übertragen.

Alexander

Ich glaube ich hab jetzt das Problem gefunden es liegt vermutlich an einer beschädigten Datenbanktabelle. Eine solche Anfrage auf eine andere Tabelle die auch ähnlich viele Datensätze enthält funktioniert nämlich einwandfrei.

Gruß
Alexander

P.S.: Kann man irgendwie die struktur der Datenbanktabelle prüfen lassen?

Warum wäre das nicht sinnvoll? Klar, wenn du Daten anforderst, wird davon ausgegangen, das du die irgendwann auch mal ansehen möchtest. Es hängt von der Implementierung ab, wann genau die Daten auch ausgelesen werden.

psql liest die Ergebnisse in der Regel sofort aus, schliesslich möchte es diese auch darstellen. Dazu wird ein Tool wie z.B. less genutzt, aber das erwartet dann die kompletten Daten als Input.

Bei einem Tool, das zu 90 % zur Entwicklung oder zum Test verwendet wird - ich hatte zumindest noch keinen Banker gesehen, der die Kontostände per psql ändert - kann man ebenfalls zu 90 % davon ausgeben, dass ich nicht alle Daten sehen will. Und wenn Zeitsyncron Mehrer auf die Idee kommen das zu tun ist auch gleich das Netz der Entwicklungsabteilung dem Kollaps nahe. Deshalb macht es keinen Sinn. Nach der Geschwindigkeit, in der die Daten am Client bei meinem ‘select’ erscheinen, wurden auch sicher nicht die ganzen Daten übertragen.

Mir ist grad noch was aufgefallen wenn der psql gekillt wird läuft der dazugehörige Postmaster weiter und verbraucht gut 90% CPU Zeit aber fast keinen Speicher. Irgendwie alles sehr seltsam.

Alexander

P. S.: Ich hab das mal ausprobiert scheinbar hast Du recht und es werden alle Daten übertragen nach dem ‘select’ werden 44% von 1 GB durch psql belegt bei dem Beispiel ‘select’. Meiner Meinung nach trotzdem nicht sinnvoll aber es scheint so zu sein. Mich wundert nur dass ich erst jetzt die Probleme damit habe mit diesen selects und dieser Produktdatenbank arbeite ich ja schon seit einem Jahr.

Wenn Du als Entwickler bei einem SELECT nicht alle Daten sehen willst, warum ist Dir dann LIMIT und OFFSET bzw. das CURSOR-Konzept unbekannt?

Und wenn Zeitsyncron Mehrer auf die Idee kommen das zu tun ist auch gleich das Netz der Entwicklungsabteilung dem Kollaps nahe.

Man kann als Entwickler immer Dummfug treiben. Sogar als Nichtentwickler.

Deshalb macht es keinen Sinn.

Exakt.

Nach der Geschwindigkeit, in der die Daten am Client bei meinem ‘select’ erscheinen, wurden auch sicher nicht die ganzen Daten übertragen.

Vor mir schwebt ein Fragezeichen.

Mir ist grad noch was aufgefallen wenn der psql gekillt wird läuft der dazugehörige Postmaster weiter und verbraucht gut 90% CPU Zeit aber fast keinen Speicher. Irgendwie alles sehr seltsam.

Alexander

vermutlich kümmert der sich ums aufräumen des von den Entwicklern verursachten Chaos…

Andreas

COPY diese in eine Datei.

Andreas

Die meisten Entwickler treiben erst mal Dummfug ausser Dir natürlich. Deine Entwicklungen sind auf anhieb Perfekt. Ich hätte nichts anderes erwartet.

Das Lesen mit Cursor ist in psql deutlich mehr Tippperei wozu wenn sich das Problem mit sinnvollem Software designe vermeiden liese.

Wie ich im ersten Posting geschrieben habe laufen meine Programme noch also benimmt sich nur psql daneben.

Und wie ich vorher bei meinem letzten Posting noch einfügte, ist mir nicht klar, warum das so plötzlich nicht mehr funktioniert. Ich hatte in den Tabellen schon mal mehr Daten und die selects liefen ohne Probleme.

Nein.

Das Lesen mit Cursor ist in psql deutlich mehr Tippperei wozu wenn sich das Problem mit sinnvollem Software designe vermeiden liese.

Wie ich im ersten Posting geschrieben habe laufen meine Programme noch also benimmt sich nur psql daneben.

psql reicht das, was $BEDIENER da reinklimpert, an die DB weiter. Ich sehe nicht ein, psql für dieses Verhalten zu rügen.

Und wie ich vorher bei meinem letzten Posting noch einfügte, ist mir nicht klar, warum das so plötzlich nicht mehr funktioniert. Ich hatte in den Tabellen schon mal mehr Daten und die selects liefen ohne Probleme.

Dann wird es eine andere Ursache haben.

Andreas

Du bleibst die Erklärung schuldig, wie dieses sinnvolle Design bei psql aussehen soll.

psql macht halt nicht anderes als deine Anfragen an die Datenbank zu reichen und dir die Antworten darzustellen. Woher soll psql wissen, das du nur die erste Seite der Ergebnisse wissen willst, obwohl da 1 Million Ergebnisse erscheinen? Für diese Einschränkungen gibt es LIMIT und OFFSET und Bonus die Datenbank kann die Anfragen passend optimieren.

Einen Teil der Daten lesen und den Rest hohlen wenn danach gefragt wird. So könnte z. B. ein anderes Design aussehen hatte ich in einem Posting weiter oben schon angedeutet. Es könnte auch die Aktion Abbrechen und eine Fehlermeldung ausgeben. Eine Anwendung kann selbst ermitteln, wie viel Speicher verfügbar ist, und muss sich selbst begrenzen. Die Grenzen, die man mit ulimit setzen kann, sind ja auch nur Notbremsen um schlecht designte oder fehlerhafte Anwendungen auf kritischen Systemen zu killen bevor der Kernel die Krise kriegt. Es ist völlig inakzeptabel ein Programm ins Blaue hinein Speicher saugen zu lassen und dann so zu tun als ob das die Top-Lösung ist.

Es gibt da ein altes Programmierer Gesetzt das leider heutzutage kaum einen mehr schert. Danach ist ein Systemabbruch in jedem Fall eine inakzeptable Reaktion einer Anwendung und ein Armutszeignis für den Programmiere der das verbrochen hat.

Das soll nicht heißen dass mir so was nicht auch schon passiert ist. Das waren aber Programmierfehler und nie eine gewollte Reaktion.

@akretschmer: Ich hab nichts dagegen dass psql das was man eingibt an den Db-Server weiter gibt. Nur was gegen die reaktion auf das was zurückkommt.

Schöne Grüße
Alexander

Der DB-Server sieht eine Bitte “Gib mir die komplette Tabelle, JETZT!” eines Clients. Soll er die nur bei schönem Wetter beantworten?

Andreas

Was willst Du dauernd mit dem Server ich hab das Client verhalten bemängelt. Der Server macht sein arbeit bisher perfekt und der Client hat die volle Kontrolle über die Verbindung zum Server nimmt er keine Daten mehr an sendet der Server auch keine mehr.

Außerdem kann der Client ja auch eine laufende Aktion bei Server abbrechen, um dem Tod zu entgehen.

Was glaubst Du würde die NASA sagen, nachdem ein paar Millionen teuerer Satellit nicht mehr erreichbar ist und der Programmierer zu Antwort gibt ich konnte ja nicht wissen, dass das Messmodul so viele Daten liefert. War halt der Speicher aus. Ich wollte nicht in der Haut des Mitarbeiters stecken. So was muss man abfangen.

Alexander

Ich verstehe ja, was du meinst, aber:

Es gibt da ein altes Programmierer Gesetzt das leider heutzutage kaum einen mehr schert. Danach ist ein Systemabbruch in jedem Fall eine inakzeptable Reaktion einer Anwendung und ein Armutszeignis für den Programmiere der das verbrochen hat.

Es gibt noch ein anderes Konzept, das bei Unix an jeder Stelle umgesetzt wird: KISS. Kleine Tools kümmern sich jeweils um ihre Angelegenheit. psql kümmert sich um das Daten holen, das Tool, as in $PAGER eingestellt ist (meistens less) kümmert sich um das darstellen. So, um bei deinem Beispiel zu bleiben: angenommen, es werden 1 Million Zeilen dargestellt und psql implementiert ein eigenes Scrolling. Was bräuchte es dafür?
Zuerst einmal müsste jede Anfrage als Cursor ausgeführt werden. Das bedeutet, das die Daten bis zum Ende des Cursors im Server bleiben (im Gegensatz zu jetzt, wo der Server “freigemacht” wird). Wenn du im Client etwas suchen möchtest, müsste der Cursor durch alle Werte durchscrollen, sprich, es müssten alle Werte vom Server zum Client übertragen werden. Beim jetzigen Verhalten liegen die alle schon beim Client im RAM. Und wenn du in der Ergebnismenge hin und herscrollst, müssten die jeweils darzustellenden Werte neu vom Server geholt werden. Das ist unter Umständen ein weit entfernter Server mit einer langsamen Anbindung, dann viel Spass.
Nicht zu vergessen, das psql ohne Unterschiede in den Parametern nicht nur als interaktiver Client genutzt wird sondern häufig auch in diversen Scripts aufgerufen wird. Hier müsste dann im Code noch eine extra Abfrage stattfinden, das bei nicht-interaktiver Anwendung eine andere Ausgabe stattfindet.

Das alles würde doppelten Code an vielen Stellen in psql erfordern, das man von KISS schon gar nicht mehr reden kann. Abgesehen von: kannst du mir eines der Standard Unix Tools nennen, das bei “Out of memory” eine gesonderte Fehlerbehandlung hat und nicht einfach abbricht?

Eine Anwendung kann selbst ermitteln, wie viel Speicher verfügbar ist, und muss sich selbst begrenzen.

Das wiederum ist schlicht falsch: auf modernen Systemen kann dir das Betriebssystem theoretisch pro Prozess erheblich mehr Speicher zur Verfügung stellen als praktisch mittels RAM und Swap verfügbar sind. Ob noch Speicher zur Verfügung steht, können dir *alloc() Routinen z.B. nur mittels Rückgabewert genau in dem Moment beim Neuanfordern von Speicher sagen … und dann ist es schon reichlich zu spät für psql.

Da ist noch ein ganz wichtiger Punkt, den du hier übersiehst: anscheinend killt der Kernel deine Anwendung aus irgendwelchen Gründen, nicht psql sich selbst. Sprich, es sieht so aus, als ob psql gar kein “nix Speicher mehr” Signal bekommt, sondern dein Kernel früher einschreitet. Kannst du mir an der Stelle sagen, wie psql darauf vernünftig reagieren soll, wenn es einfach weggekillt wird?


@akretschmer: Ich hab nichts dagegen dass psql das was man eingibt an den Db-Server weiter gibt. Nur was gegen die reaktion auf das was zurückkommt.

Ach, weisst du, ich spiele den Ball einfach mal zurück: schick einen Patch ein, schauen wir, ob er angenommen wird.
Wozu ist PostgreSQL freie Software?

Das hat nix mit dem Unix-Konzept zu tun.

Wie stellen Deine Modernen Systeme Speicher zur Verfügung der weder als RAM noch als SWAP auf Platte liegt. Kernel an nirwana bitte sende Speicher.
:smiley:

Das geht auch ohne Cursor. Es ist ja auch nicht erwünscht dass der SQL vom User verändert wird. Der soll wie eingegeben ausgeführt werden.

Interessant schauen Deine Scripte auch per less die Daten an. Wenn psql in einem Script eingesetzt wird muß die Ausgabe so anders erfolgen und nicht über less. Na und ein if mehr wird doch keinen umbringen.

Mit der Fehlerbehandlung in anderen Unix-Tools kann ich nur Raten. Ich habe es aber z.B. bei vi, grep, ls, find usw. noch nie erlebt dass eines vom Kernel gekillt werden mußte.

Der Linux-Kernel killt Anwendungen die die Systemstabilität gefährden und wenn RAM und SWAP voll ist wir der verursacher gekillt. Es liegt in der Verantwortung der Anwendung dafür zu sorgen dass genau das nicht passiert. Es ist auch jeden fall nicht richtig dass eine Anwendung das nicht prüfen kann. Mindestens der Kernel stellt entsprechende Funktionen zur Verfügung. Meiner Meinung nach gibt es diese auch in der glibc. Für Speicherintensive Anwendungen wie die Berechnung von 3D-Grafiken oder Animationen sind diese lebenswichtig denn wenn die Anwendung nach auf gut Glück speicher saugt werden sollche Programme nie fertig weil nach kurzer Zeit der kill wegen Speichermangel kommt.

Wenn Du die Kommunikation mit den Entwicklern übernimmst. Dafür sind meine Englischkenntnisse nicht gut genug. Dann könnte ich mal überlegen was man machen müsste um eine Anwendungsseitige Notbremse zu realisieren.

Alexander