J'ai besoin d'indications sur la façon de diagnostiquer et de résoudre ce problème. Je ne sais pas s'il s'agit d'un simple problème d'installation du serveur ou d'un problème de conception d'application (ou des deux).
Une ou deux fois par mois, cette base de données Oracle XE signale des erreurs ORA-4031. Cela ne pointe pas systématiquement vers une partie particulière de la sga. Un exemple récent est:
ORA-04031: unable to allocate 8208 bytes of shared memory ("large pool","unknown object","sort subheap","sort key")
Lorsque cette erreur se produit, si l'utilisateur continue d'actualiser ses données en cliquant sur différents liens, il obtiendra généralement davantage de ce type d'erreurs à des moments différents. Bientôt, il obtiendra les erreurs de page "404 non trouvés".
Le redémarrage de la base de données résout généralement le problème pendant un certain temps, puis environ un mois plus tard, il revient, mais rarement au même endroit du programme (c’est-à-dire qu’il ne semble pas lié à une partie de code particulière) (l’exemple ci-dessus). une erreur a été générée à partir d'une page Apex qui triait plus de 5 000 lignes d'une table).
J'ai essayé d'augmenter sga_max_size
de 140M à 256M et j'espère que cela aidera les choses. Bien sûr, je ne saurai pas si cela a aidé depuis que j'ai dû redémarrer la base de données pour changer les paramètres :)
J'utilise Oracle XE 10.2.0.1.0 sur une machine Oracle Enterprise Linux 5 avec 512 Mo de RAM. Le serveur exécute uniquement la base de données, Oracle Apex (v3.1.2) et le serveur Web Apache. Je l'ai installé avec à peu près tous les paramètres par défaut et il fonctionne assez bien depuis environ un an. La plupart des problèmes que j'ai pu résoudre moi-même en ajustant le code de l'application; il n'est pas utilisé de manière intensive et n'est pas un système critique pour l'entreprise.
Je pense que certains paramètres actuels peuvent être pertinents:
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
Si cela vous aide, voici les tailles SGA actuelles:
Total System Global Area 268435456 bytes
Fixed Size 1258392 bytes
Variable Size 251661416 bytes
Database Buffers 12582912 bytes
Redo Buffers 2932736 bytes
Même si vous utilisez ASMM, vous pouvez définir une taille minimale pour le grand pool (MMAN ne le réduira pas en dessous de cette valeur) . Vous pouvez également essayer d'épingler certains objets et d'augmenter SGA_TARGET.
N'oubliez pas de fragmentation. Si vous avez beaucoup de trafic, vos pools peuvent être fragmentés et même si vous avez plusieurs Mo disponibles, il ne peut y avoir de bloc supérieur à 4 Ko . Vérifiez la taille du plus grand bloc libre avec une requête du type:
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);
Toutes les réponses actuelles traitent du symptôme (épuisement du pool de mémoire partagée) et non du problème, qui consiste à ne pas utiliser de variables de liaison dans vos requêtes sql\JDBC, même si cela ne semble pas nécessaire. Passer des requêtes sans variables de liaison oblige Oracle à "analyser en profondeur" la requête à chaque fois, en déterminant son plan d'exécution, etc.
https://asktom.Oracle.com/pls/asktom/f?p=100:11:::::p11_question_id:528893984337
Quelques extraits du lien ci-dessus:
"Java prend en charge les variables de liaison, vos développeurs doivent commencer par utiliser des instructions préparées et y lier des entrées. Si vous souhaitez que votre système évolue au-delà de 3 ou 4 utilisateurs, vous le ferez maintenant Ce n’est pas quelque chose à penser, c’est une chose que vous DEVEZ faire. Un effet secondaire: vos problèmes de piscine partagés disparaîtront à peu près. C’est la cause fondamentale. "
"La manière dont fonctionne le pool partagé Oracle (une structure de données en mémoire partagée très importante) Est basée sur le fait que les développeurs utilisent des variables de liaison."
"Les variables de liaison sont SO MASSIVEMENT importantes - je ne peux en aucune façon donner forme ou surestimer leur importance."
Les éléments suivants ne sont pas nécessaires car ils ne résolvent pas l'erreur:
Le redémarrage de la base de données va vider votre piscine et cela résout un effet et non le problème.
Fixez votre large_pool afin qu'il ne puisse pas descendre plus bas qu'un certain point ou ajouter de la mémoire et définir une mémoire maximale plus élevée.