この問題を診断および修正する方法についてのポインターが必要です。これが単純なサーバー設定の問題なのか、アプリケーションの設計の問題なのか(あるいはその両方)なのかわかりません。
数か月に1〜2回、このOracle XEデータベースはORA-4031エラーを報告します。スガの特定の部分を一貫して指すわけではありません。最近の例は次のとおりです。
ORA-04031: unable to allocate 8208 bytes of shared memory ("large pool","unknown object","sort subheap","sort key")
このエラーが発生した場合、ユーザーがさまざまなリンクをクリックして更新し続けると、通常はこれらの種類のエラーがさまざまな時間に発生し、すぐに「404 not found」ページエラーが発生します。
通常、データベースを再起動すると、しばらくの間問題が解決し、その後1か月程度後に再び問題が発生しますが、プログラム内の同じ場所ではめったに起こりません(つまり、コードの特定の部分にリンクされていないようです)(上記の例テーブルから5000行以上をソートしているApexページからエラーが発生しました)。
sga_max_size
を140Mから256Mに増やしてみましたが、これが物事の助けになることを願っています。もちろん、設定を変更するためにデータベースを再起動しなければならなかったので、これが役立ったかどうかはわかりません:)
512 MBのRAMを搭載したOracle Enterprise Linux 5ボックスでOracle XE 10.2.0.1.0を実行しています。サーバーは、データベース、Oracle Apex(v3.1.2)、およびApache Webサーバーのみを実行します。ほぼすべてのデフォルトパラメータを使用してインストールしましたが、1年ほど実行されています。ほとんどの問題は、アプリケーションコードを調整することで解決できました。集中的に使用されておらず、ビジネスに不可欠なシステムではありません。
これらは関連があると思われる現在の設定です。
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
何か助けがあれば、現在のSGAサイズを以下に示します。
Total System Global Area 268435456 bytes
Fixed Size 1258392 bytes
Variable Size 251661416 bytes
Database Buffers 12582912 bytes
Redo Buffers 2932736 bytes
ASMMを使用している場合でも、ラージプールの最小サイズを設定できます(MMANはそれをその値以下に縮小しません)。一部のオブジェクトを固定して、SGA_TARGETを増やしてみることもできます。
断片化を忘れないでください。大量のトラフィックがある場合、プールは断片化される可能性があり、数MBの空きがある場合でも、4 KBを超えるブロックはありません。次のようなクエリで最大空きブロックのサイズを確認します。
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);
現在の回答はすべて、症状(共有メモリプールの枯渇)に対処するものであり、SQL\JDBCクエリでバインド変数を使用していない可能性がある場合でも、バインド変数を使用していない可能性があります。バインド変数なしでクエリを渡すと、Oracleは毎回クエリを「ハード解析」し、実行計画などを決定します。
https://asktom.Oracle.com/pls/asktom/f?p=100:11:0::::p11_question_id:528893984337
上記のリンクからの抜粋:
「Javaはバインド変数をサポートしているため、開発者は準備されたステートメントの使用を開始し、入力をバインドする必要があります。考えるべきことではなく、あなたがしなければならないことです。この副作用-共有プールの問題はほとんどなくなるでしょう。それが根本的な原因です。
「Oracle共有プール(非常に重要な共有メモリデータ構造)の動作方法は、バインド変数を使用する開発者に基づいています。」
「バインド変数はSO非常に重要です-私は決してその重要性を形作ることも形作ることもできません。」
以下は、エラーを修正しないため必要ありません。
データベースを再起動するとプールがフラッシュされ、問題ではなく効果が解決されます。
特定のポイントより低くなったり、メモリを追加して最大メモリを大きく設定したりできないように、large_poolを修正します。