PDA

View Full Version : MCH2803 Speicherfehler



Seiten : [1] 2

Joe
17-05-11, 13:02
Hallo Forum.

Im Joblog eines Benutzers finde ich plötzlich folgende Fehlermeldungen:

MCH2803 Speicherbereich der Maschine wurde überschritten.
*** DBOP open FAILED. Exception from call to SLICÜ ***.
Interner Fehler im Abfrageprozessor.
SQL-Systemfehler.
Datei QAP0ZDMP in Bibliothek QTEMP bereits vorhanden.
Auszug der BenutzerTrace-Daten für Job 404667/BRENNER/TERM190S3 in
Teildatei QP0Z404667 in Datei QAP0ZDMP in Bibliothek QTEMP gestellt.

Die Meldungen resultieren aus einem SQLRPGLE.
Der Benutzer erhält keine Fehlermeldung.
Was kann die Ursache für diese Meldungen sein?

OS: V5R4

Gruß Joe

Fuerchau
17-05-11, 13:10
Zuwenig Hauptspeicher zur Verfügung.
Die Abfrage, die hier per SQL gemacht wird, scheint mehr Hauptspeicher zu benötigen als eben verfügbar ist (was eigentlich sehr unwahrscheinlich ist).

Ggf. mal die Abfrage die da gemacht wird kontrollieren und ansonsten eine Meldung an IBM abgeben.
Es könnte sich auch um einen Fehler des SQL-Abfragegenerators handeln.

Ggf. mal mit WRKSYSSTS die Speichergrößen prüfen und ob in der Spalte "Wart.n.Wäh", "Aktiv n.wäh" Werte > 0 auftauchen.
Dies deutet dann auf massive Speicherengpässe hin.

holgerscherer
18-05-11, 07:22
[B]MCH2803 Speicherbereich der Maschine wurde überschritten.

Hallo Joe,
ist der User in seiner Speicherkapazität beschränkt? Wenn ja, platzt die Grenze vielleicht wegen möglicher temporärer Auswüchse des Optimiziers. Ansonsten: PTF-Stand? :)

-h

Joe
18-05-11, 16:40
Hallo Joe,
ist der User in seiner Speicherkapazität beschränkt? Wenn ja, platzt die Grenze vielleicht wegen möglicher temporärer Auswüchse des Optimiziers. Ansonsten: PTF-Stand? :)

-h

Bei der Anzeige offene Dateien ist mir aufgefallen, dass
Dateien mehrfach vorhanden sind. Das wiederholt sich auf
mehreren Seiten.
s.auch Anzahl Datenpfade.
Die Datei YPFLOSD z.B. wird in SQLRPGLE verarbeitet. Warum wird die nicht geschlossen ?

Anzahl offener Datenpfade . : 168


Teildatei/
Datei Bibliothek Einheit
YLFDASKB DATALIB YLFDASKB
YLFDASFA DATALIB YLFFDASFA
*QUERY0001 QTEMP *QUERY0001
YLFDASFA DATALIB YLFDASFA
YPFFST DATALIB YPFFST
YPFLOSD DATALIB YPFLOSD
YPFDKV DATALIB YPFDKV
YLFLOSD DATALIB YLFLOSD
YPFLOSD DATALIB YPFLOSD
YPFLOSD DATALIB YPFLOSD
YLFLOSD DATALIB YLFLOSD

Bereich und Aktivierungsgruppe jeweils
*ACTGRPDFN *DFTACTGRP 00000000000002

Bin für weitere Hinweise dankbar.

Gruß
Joe

Fuerchau
18-05-11, 17:08
Dies deutet vor allem auf nicht geschlossene Cursor und ggf. viele verschiedene dynamische SQL's hin.

Der SQL-Optimizer hält Dateien offen (ODP's) wenn der selbe Zugriff mindestens 2 Mal erfolgt.
Aber selbst wenn man verschiedene SQL's absetzt und vorherige Cursor auch korrekt geschlossen werden, werden normalerweise die ODP's wieder verwendet.

Wenn immer wieder die selbe Datei geöffnet wird, deutet das eben auf fehlende "Close Curser" hin.

Selbst bei dynamischen SQL's kann ich in Cobol/RPG keine dynamischen Cursor-Namen vergeben, so dass ich eigentlich erst einen Close machen muss bevor ich für den selben Cursor ein neues Statement prepare.

Ggf. sollte man vor einem Prepare Statement ein Drop Statement einbauen.

Arbeitet man ggf. mit dem CLI-Interface (C-Befehle SQLxxxx), kann man natürlich auch Cursor dynamisch anlegen.

Zusammen gefasst:
Zu viele geöffnete Cursor, irgendwann platzt halt das System.

Nur so zur Info:
Als ich bei einer Verbindung zu einer Oracle-Datenbank vergessen hatte neben dem Close Cursor auch ein Drop Statement einzubauen, war auch nach ca. 1000 Abfragen mit der Meldung "Ressourcen überschritten" Schluss.

B.Hauser
19-05-11, 06:01
Wir müssen zwischen impliziten und expliziten Schließen eines Cursors unterscheiden.

Das SQL Statement CLOSE schließt einen Cursor, lässt jedoch die ODPs (nach dem 2. Durchlauf) stehen, sofern diese wiederverwendbar sind.

Jedes SQL Statement erhält seinen eigenen ODP, auch dann, wenn das gleiche SQL Statement mehrfach in unterschiedlichen Subroutinen, Prozeduren oder Programmen codiert wurde.

Wann ein Cursor explizit geschlossen wird hängt von der Compile Option CLOSQLCSR ab. Der Default-Wert ist *ENDACTGRP, d.h. die ODPs werden erst dann gelöscht wenn die Aktivierungsgruppe beendet wird. Wird die Option *ENDMOD verwendet, wird der ODP gelöscht sobald das Modul, in dem das SQL-Statement hinterlegt wurde beendet wird. (Da eine volle Optimierung bzw. das Aufbauen der ODPs zeitaufwendig ist, ist aus Performance-Geschichtspunkten die erste Möglichkeit die bessere).

So wie es aussieht werden alle Programme in der Default-Activation-Group ausgeführt. Und die Default-Activation-Group kann nur durch das Beenden des Jobs beendet werden.

Die Anzahl der geöffneten bzw. offengehaltenen ODPs ist auch nicht unendlich, sondern soweit ich weiß per Default 512 pro Job. Ist dieses Maximum erreicht, so wird der älteste bzw. der am längsten nicht verwendete ODP gelöscht und durch den neuen ersetzt. In der QAQQINI (Abfrage Optionsdatei) gibt es Optionen, über die auf die Anzahl der ODPs pro Job Einfluss genommen werden kann.

Trotzallem bei "SQL-System Fehler" würde ich IBM einen Fehler melden.

Birgitta

Fuerchau
19-05-11, 08:25
Ich hatte auch schon mehr als 1000 ODP's in einem ODBC-Job.
Der Close eines ODP's kann nur erfolgen, wenn auch tatsächlich der Cursor geschlossen wird, da ein Cursor sich schließlich auf die aktuellen Satzzeiger der ODP's verlassen muss.
Ein ODP kann nur wiederverwendet werden, wenn dieser eben frei ist.

Bei dynamischen SQL ist eben ein Close und Drop Statement wichtig um den ODP wiederverwendbar zu machen.

B.Hauser
19-05-11, 09:25
Der Close eines ODP's kann nur erfolgen, wenn auch tatsächlich der Cursor geschlossen wird, da ein Cursor sich schließlich auf die aktuellen Satzzeiger der ODP's verlassen muss.
Ein ODP kann nur wiederverwendet werden, wenn dieser eben frei ist.

Ich hatte ja auch nichts anderes behauptet!!!
Man muss zwischen implizitem Schließen (SQL Statement CLOSE) und explizitem Schließen (Löschen des ODPs) unterscheiden.

Ein ODP kann natürlich nur gelöscht werden wenn der Cursor implizit geschlossen wurde (das CLOSE-Statement) ausgeführt wurde.
Ein geöffneter Cursor ist noch in Verwendung und wird daher auch nicht (automatisch) gelöscht.

Birgitta

BenderD
19-05-11, 09:38
... das geht ja wieder mal heftig durcheinander...
- wenn ich im Programm ein close statement absetze, ist das ein expliziter close!!!
- wenn ich im Programm kein close absetze und CLOSSQLCSR(*ENDMOD) gesetzt habe, schließt die runtime den Cursor implizit, das nennt man so, weil das verlassen des Modules den close beinhaltet!!!
- beide Operationen sind seit langem nur logische Operationen (Stichwort: lazy close), ob die Datenbank tatsächlich schließt (hard close), ist das Bier der Datenbank - könnte sich sogar mit dem nächsten PTF wieder ändern!!!
- Performance relevant ist das, wenn mit dem öffnen des ODPs ein Index erzeugt werden muss, weil kein passender da ist!!!
- Performance relevant ist das, wenn die Anwendung wg. fehlender logischer Close Operationen zu viele Cursor offen halten muss - dann steht sie nämlich!!!
- öffnen eines ODP ohne neuen Optimize (static SQL) und ohne Index Aufbau (passender vorhanden), dauert Millisekunden, Perfomance relevant ist das selbst in heftigen Fällen nicht, egal wie oft das noch behauptet wird!!!

D*B


Man muss zwischen implizitem Schließen (SQL Statement CLOSE) und explizitem Schließen (Löschen des ODPs) unterscheiden.

Ein ODP kann natürlich nur gelöscht werden wenn der Cursor implizit geschlossen wurde (das CLOSE-Statement) ausgeführt wurde.
Ein geöffneter Cursor ist noch in Verwendung und wird daher auch nicht (automatisch) gelöscht.

Birgitta

Joe
19-05-11, 11:10
Wir müssen zwischen impliziten und expliziten Schließen eines Cursors unterscheiden.

Das SQL Statement CLOSE schließt einen Cursor, lässt jedoch die ODPs (nach dem 2. Durchlauf) stehen, sofern diese wiederverwendbar sind.

Jedes SQL Statement erhält seinen eigenen ODP, auch dann, wenn das gleiche SQL Statement mehrfach in unterschiedlichen Subroutinen, Prozeduren oder Programmen codiert wurde.

Wann ein Cursor explizit geschlossen wird hängt von der Compile Option CLOSQLCSR ab. Der Default-Wert ist *ENDACTGRP, d.h. die ODPs werden erst dann gelöscht wenn die Aktivierungsgruppe beendet wird. Wird die Option *ENDMOD verwendet, wird der ODP gelöscht sobald das Modul, in dem das SQL-Statement hinterlegt wurde beendet wird. (Da eine volle Optimierung bzw. das Aufbauen der ODPs zeitaufwendig ist, ist aus Performance-Geschichtspunkten die erste Möglichkeit die bessere).

So wie es aussieht werden alle Programme in der Default-Activation-Group ausgeführt. Und die Default-Activation-Group kann nur durch das Beenden des Jobs beendet werden.

Die Anzahl der geöffneten bzw. offengehaltenen ODPs ist auch nicht unendlich, sondern soweit ich weiß per Default 512 pro Job. Ist dieses Maximum erreicht, so wird der älteste bzw. der am längsten nicht verwendete ODP gelöscht und durch den neuen ersetzt. In der QAQQINI (Abfrage Optionsdatei) gibt es Optionen, über die auf die Anzahl der ODPs pro Job Einfluss genommen werden kann.

Trotzallem bei "SQL-System Fehler" würde ich IBM einen Fehler melden.

Birgitta

Erstmal Danke an alle.

Da habe ich ja wieder eine interessante Diskussion losgetreten.

Zum Thema:
Die Programme werden mit CLOSQLCSR *ENDACTGRP kompiliert.

(Wird von mir verwendet, weil bei *ENDMOD und häufigen Calls auf SQLRPGLE eine Verschlechterung der Performance eintritt. )

Es gibt nur statische SQL. d.H. Declare/open/fetch/close,
keine dynam. (Prepare,declare,fetch...)
Und wenn der älteste bzw. der am längsten nicht verwendete ODP bei Maximum gelöscht wird, bleibt nur die Empfehlung von Birgitta: "SQL-System Fehler" an IBM melden ?

Gruß Joe