web-dev-qa-db-ja.com

ORA-4031「xバイトの共有メモリーを割り当てることができません」の解決

この問題を診断および修正する方法についてのポインターが必要です。これが単純なサーバー設定の問題なのか、アプリケーションの設計の問題なのか(あるいはその両方)なのかわかりません。

数か月に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
22
Jeffrey Kemp

ASMMを使用している場合でも、ラージプールの最小サイズを設定できます(MMANはそれをその値以下に縮小しません)。一部のオブジェクトを固定して、SGA_TARGETを増やしてみることもできます。

7
Kathryn

断片化を忘れないでください。大量のトラフィックがある場合、プールは断片化される可能性があり、数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);

コードから

5
slovon

現在の回答はすべて、症状(共有メモリプールの枯渇)に対処するものであり、SQL\JDBCクエリでバインド変数を使用していない可能性がある場合でも、バインド変数を使用していない可能性があります。バインド変数なしでクエリを渡すと、Oracleは毎回クエリを「ハード解析」し、実行計画などを決定します。

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

上記のリンクからの抜粋:

「Javaはバインド変数をサポートしているため、開発者は準備されたステートメントの使用を開始し、入力をバインドする必要があります。考えるべきことではなく、あなたがしなければならないことです。この副作用-共有プールの問題はほとんどなくなるでしょう。それが根本的な原因です。

「Oracle共有プール(非常に重要な共有メモリデータ構造)の動作方法は、バインド変数を使用する開発者に基づいています。」

「バインド変数はSO非常に重要です-私は決してその重要性を形作ることも形作ることもできません。」

2
mancini0

以下は、エラーを修正しないため必要ありません。

  1. 1 ps -ef | grep Oracle
  2. スモンを見つけて、それのためにPIDを殺します
  3. SQL>スタートアップマウントSQL>
  4. Spfileからpfileを作成します。

データベースを再起動するとプールがフラッシュされ、問題ではなく効果が解決されます。

特定のポイントより低くなったり、メモリを追加して最大メモリを大きく設定したりできないように、large_poolを修正します。

0
Tonny de Groot