2017-01-06 3 views
0

Ich habe Jobs in Oracle, die stundenlang eine Menge Berechnungen mit XmlTransform ausführen können (aber nicht beschränkt auf). Ich habe festgestellt, dass der PGA-Speicher allmählich zunimmt (und die Leistung abnimmt), bis der Job irgendwann mit einer PGA-Meldung (Out of Memory) ausfällt. Wir haben einige Korrekturen angewendet, aber sie scheinen das Problem nicht zu lösen. Stoppen der Jobs und neu starten, löst mein Problem, die Leistung ist wieder gut und der Speicher ist niedrig ... Der gesamte Code ist in PL/SQL und SQL geschrieben.So umgehen Sie ein Speicherleck in Oracle

Frage: Da ich so schnell wie möglich lösen möchte, habe ich mich gefragt, wie ich diese Art von Problem in Oracle umgehen kann.

Mein Haupt Denken geht irgendwie:

  • den Auftrag nach einiger Zeit neu zu starten (möglicherweise die einfachste Lösung) mit Advanced Queuing
  • Neustart der aktuellen Sitzung?
  • Code synchron in einer anderen Sitzung ausführen, vielleicht ein anderer Job.

Oracle 12.1.0.2

EDIT: Als Beispielcode mit XmlTransform hier gefragt:

function i_Convert_Xml_To_Clob (p_Zoek_Result_Type_Id in Zoek_Result_Type.Zoek_Result_Type_Id%type, 
           p_Xml     in xmltype, 
           p_Xml_Transformation in xmltype) return clob is 
    mResult clob; 
begin 
    if p_Xml_Transformation is not null then 
    select Xmltransform (p_Xml, p_Xml_Transformation).getclobval() 
     into mResult 
    from Dual; 
    elsif p_Xml is not null then 
    mResult := p_Xml.getclobval(); 
    else 
    mResult := null; 
    end if; 

    return mResult; 
end i_Convert_Xml_To_Clob; 
+0

Warum nennen Sie es ein Speicherleck? Sie müssen Ihren Job optimieren, um effizienter zu sein, oder der Datenbank mehr Speicher zur Verfügung stellen, damit sie die Arbeit ausführen kann, die Sie tun möchten – thatjeffsmith

+0

@thatjeffsmith wie erwähnt, die Speicherauslastung nimmt zu, sollte aber nicht sein . Ich habe den Code sehr gut abgestimmt, konnte aber keine mögliche Quelle für den Anstieg finden. Ich kann die Jobs irgendwie neu starten, aber das ist leichter gesagt als getan. – rvheddeg

+2

Ja, aber wir können Ihnen nicht helfen - Sie müssen uns Ihren Code zeigen, Ihre Spuren, zeigen Sie uns, warum die Erinnerung zunimmt und warum Sie denken, dass es nicht sein sollte – thatjeffsmith

Antwort

2

Können Sie oder ein DBA Monitor Temp lob Verwendung von einer anderen Sitzung V $ TEMPORARY_LOBS verwenden. Wenn die Anzahl der Lobs ansteigt, befreit die Sitzung sie nicht korrekt und dies führt zu einer erhöhten PGA-Nutzung (dies ist kein Leck).

Das am häufigsten auftretende Szenario ist die Verarbeitung einer Anweisung, die einen oder mehrere temporäre LOBs zurückgibt, z. B. XMLTRANSMFORM(). GetClobVal(). Es ist nicht ungewöhnlich, dass (Java?) - Entwickler vergessen, dass ein TEMP-LOB ein SESSION-Level-Objekt ist und die damit verknüpften Ressourcen nicht freigegeben werden, wenn das Client-Handle oder die Referenz den Gültigkeitsbereich verlassen. Wenn Sie beispielsweise einen TEMP-Lob in ein JAVA-Clob-Objekt erhalten, können Sie sich nicht auf die Garbage Collection verlassen, um das LOB zu bereinigen. Sie müssen den Lob explizit freigeben, bevor Sie ihn mit dem nächsten Lob überschreiben, oder die LOB-Ressourcen werden bis zum Ende der Sitzung vom Server gehalten.

Da wir keinen Beispielcode haben, können wir nicht definitiv angeben, was in Ihrem Fall passiert.

+0

Mein gesamter Code ist in PL/SQL und SQL geschrieben. Bleibt Ihre Erklärung dann noch? Ich werde versuchen, den Lob nach der xmltransform freizugeben. – rvheddeg

+0

Es kommt darauf an, ein reines PL/SQL-Verfahren, das die Ausgabe der Transformation nicht zurückgibt (zB speichert es in der Datenbank) _should_ muss sich nicht darum kümmern, den Temp Lob zu befreien, aber es ist immer noch gute Praxis. Sobald ein beliebiges der in PL/SQL erzeugten LOBs an einen Client übergeben wird, werden die LOBS zu Objekten auf Sitzungsebene und müssen freigegeben werden. –

+0

Wieder müssen wir wirklich den Code und alle zugehörigen Client-Code sehen, um sicher zu sein. Wenn es sich um eine reine PL/SQL-Lösung handelt, sollten Sie V $ TEMPORARY_LOBS vom PL/SQL-Block abfragen und die Anzahl der LOBS mit DBMS_OUTPUT ausgeben können. –