it-swarm.com.de

Lösung für ORA-4031: "x Bytes des gemeinsam genutzten Speichers können nicht zugewiesen werden"

Ich benötige einige Hinweise zur Diagnose und Behebung dieses Problems. Ich weiß nicht, ob dies ein einfaches Server-Setup-Problem oder ein Anwendungsdesign-Problem (oder beides) ist.

Ein- oder zweimal alle paar Monate meldet diese Oracle XE-Datenbank ORA-4031-Fehler. Es zeigt nicht konsequent auf einen bestimmten Teil der SGA. Ein aktuelles Beispiel ist:

ORA-04031: unable to allocate 8208 bytes of shared memory ("large pool","unknown object","sort subheap","sort key")

Wenn dieser Fehler auftritt und der Benutzer ständig auffrischt, indem er auf verschiedene Links klickt, werden im Allgemeinen zu verschiedenen Zeitpunkten mehr solcher Fehler angezeigt, und bald werden Seitenfehler "404 not found" (404 nicht gefunden) angezeigt.

Durch einen Neustart der Datenbank wird das Problem in der Regel für eine Weile behoben. Nach etwa einem Monat wird es erneut angezeigt, jedoch selten an derselben Stelle im Programm (dh, es scheint nicht mit einem bestimmten Codeabschnitt verknüpft zu sein) (obiges Beispiel) Ein Fehler wurde von einer Apex-Seite ausgelöst, auf der mehr als 5000 Zeilen aus einer Tabelle sortiert wurden.

Ich habe versucht, den sga_max_size von 140M auf 256M zu erhöhen, und hoffe, dass dies Abhilfe schafft. Natürlich weiß ich nicht, ob dies geholfen hat, da ich die Datenbank neu starten musste, um die Einstellung zu ändern :)

Ich verwende Oracle XE 10.2.0.1.0 auf einer Oracle Enterprise Linux 5-Box mit 512 MB RAM. Auf dem Server werden nur die Datenbank, Oracle Apex (Version 3.1.2) und der Apache-Webserver ausgeführt. Ich habe es mit so ziemlich allen Standardparametern installiert und es läuft seit ungefähr einem Jahr ziemlich gut. Die meisten Probleme konnte ich selbst beheben, indem ich den Anwendungscode optimierte. Es wird nicht intensiv genutzt und ist kein geschäftskritisches System.

Dies sind einige aktuelle Einstellungen, von denen ich denke, dass sie relevant sind:

pga_aggregate_target        41,943,040
sga_max_size              268,435,456
sga_target                146,800,640
shared_pool_reserved_size   5,452,595
shared_pool_size          104,857,600

Hier finden Sie die aktuellen SGA-Größen:

Total System Global Area  268435456 bytes
Fixed Size                  1258392 bytes
Variable Size             251661416 bytes
Database Buffers           12582912 bytes
Redo Buffers                2932736 bytes
21
Jeffrey Kemp

Obwohl Sie ASMM verwenden, können Sie eine Mindestgröße für den großen Pool festlegen (MMAN verkleinert ihn nicht unter diesen Wert). Sie können auch versuchen, einige Objekte zu pinnen und SGA_TARGET zu erhöhen.

6
Kathryn

Vergiss die Fragmentierung nicht. Wenn Sie viel Verkehr haben, können Ihre Pools fragmentiert sein, und selbst wenn Sie mehrere MB frei haben, könnte kein Block größer als 4 KB sein. __ Überprüfen Sie die Größe des größten freien Blocks mit der folgenden Abfrage:

 select
  '0 (<140)' BUCKET, KSMCHCLS, KSMCHIDX,
  10*trunc(KSMCHSIZ/10) "From",
  count(*) "Count" ,
  max(KSMCHSIZ) "Biggest",
  trunc(avg(KSMCHSIZ)) "AvgSize",
  trunc(sum(KSMCHSIZ)) "Total"
from
  x$ksmsp
where
  KSMCHSIZ<140
and
  KSMCHCLS='free'
group by
  KSMCHCLS, KSMCHIDX, 10*trunc(KSMCHSIZ/10)
UNION ALL
select
  '1 (140-267)' BUCKET,
  KSMCHCLS,
  KSMCHIDX,
  20*trunc(KSMCHSIZ/20) ,
  count(*) ,
  max(KSMCHSIZ) ,
  trunc(avg(KSMCHSIZ)) "AvgSize",
  trunc(sum(KSMCHSIZ)) "Total"
from
  x$ksmsp
where
  KSMCHSIZ between 140 and 267
and
  KSMCHCLS='free'
group by
  KSMCHCLS, KSMCHIDX, 20*trunc(KSMCHSIZ/20)
UNION ALL
select
  '2 (268-523)' BUCKET,
  KSMCHCLS,
  KSMCHIDX,
  50*trunc(KSMCHSIZ/50) ,
  count(*) ,
  max(KSMCHSIZ) ,
  trunc(avg(KSMCHSIZ)) "AvgSize",
  trunc(sum(KSMCHSIZ)) "Total"
from
  x$ksmsp
where
  KSMCHSIZ between 268 and 523
and
  KSMCHCLS='free'
group by
  KSMCHCLS, KSMCHIDX, 50*trunc(KSMCHSIZ/50)
UNION ALL
select
  '3-5 (524-4107)' BUCKET,
  KSMCHCLS,
  KSMCHIDX,
  500*trunc(KSMCHSIZ/500) ,
  count(*) ,
  max(KSMCHSIZ) ,
  trunc(avg(KSMCHSIZ)) "AvgSize",
  trunc(sum(KSMCHSIZ)) "Total"
from
  x$ksmsp
where
  KSMCHSIZ between 524 and 4107
and
  KSMCHCLS='free'
group by
  KSMCHCLS, KSMCHIDX, 500*trunc(KSMCHSIZ/500)
UNION ALL
select
  '6+ (4108+)' BUCKET,
  KSMCHCLS,
  KSMCHIDX,
  1000*trunc(KSMCHSIZ/1000) ,
  count(*) ,
  max(KSMCHSIZ) ,
  trunc(avg(KSMCHSIZ)) "AvgSize",
  trunc(sum(KSMCHSIZ)) "Total"
from
  x$ksmsp
where
  KSMCHSIZ >= 4108
and
  KSMCHCLS='free'
group by
  KSMCHCLS, KSMCHIDX, 1000*trunc(KSMCHSIZ/1000);

Code von

5
slovon

Alle aktuellen Antworten beziehen sich auf das Symptom (Erschöpfung des gemeinsam genutzten Speicherpools) und nicht auf das Problem, das wahrscheinlich keine Bindungsvariablen in Ihren sql\JDBC-Abfragen verwendet, selbst wenn dies nicht notwendig erscheint. Das Übergeben von Abfragen ohne Bindungsvariablen führt dazu, dass Oracle die Abfrage jedes Mal "hart analysiert", um ihren Ausführungsplan festzulegen usw. 

https://asktom.Oracle.com/pls/asktom/f?p=100:11::::p11_question_id:528893984337

Einige Ausschnitte aus dem obigen Link:

"Java unterstützt Bind-Variablen. Ihre Entwickler müssen vorbereitete Anweisungen verwenden und Eingaben darin binden. Wenn Sie möchten, dass Ihr System letztendlich nicht nur etwa drei oder vier Benutzer umfasst, werden Sie dies sofort tun (den Code korrigieren) Es ist nichts, worüber man nachdenken muss, es ist etwas, das Sie tun müssen. Ein Nebeneffekt - Ihre gemeinsamen Poolprobleme werden so gut wie verschwinden. Das ist die Ursache. "

"Die Art und Weise, in der der gemeinsam genutzte Oracle-Pool (eine sehr wichtige Shared-Memory-Datenstruktur) Arbeitet, wird von Entwicklern mit Bindungsvariablen festgelegt."

"Bind-Variablen sind SO MASSIV wichtig - ich kann ihre Bedeutung in keiner Weise beeinflussen."

2
mancini0

Folgendes wird nicht benötigt, da sie den Fehler nicht beheben:

  1. 1 ps -ef | grep Oracle
  2. Finde den Smon und töte die Pid dafür
  3. SQL> Startup-SQL> 
  4. Pfeile aus Spfile erstellen;

Durch einen Neustart der Datenbank wird der Pool geleert. Dadurch wird ein Effekt behoben, der nicht das Problem ist.

Fixiere deinen large_pool so, dass er nicht unter einen bestimmten Punkt gehen kann, oder füge Speicher hinzu und setze einen höheren maximalen Speicher.

0
Tonny de Groot