PGAサイズが多すぎるとシステムに多い問題を起こします。非正常的なPGAサイズの問題を分析する最高の方法はPGAヒープダンプを落としてそれを精密分析することです。しかし、PGAのサイズ増加が速すぎる場合は手動的にダンプコマンドを実行するのはむずかしいはずです。
幸い、オラクルが提供する診断イベントを活用すればPGAヒープダンプを自動的かすることができます。
1. まず、10261診断イベントを通じてPGAヒープダンプサイズを制限します。たとえば、下記のコマンドでPGAヒープサイズを100000KBに制限できます。
alter system set events '10261 trace name context forever, level 100000';
2. 10261イベントが存在する場合、PGAのサイズが設定したサイズを超えるプロセスはORA-600 [723]エラーとともに失敗します。
-- make big pga
declare
type varchar2_array is table of varchar2(32767) index by pls_integer;
vc varchar2_array;
v varchar2(32767);
begin
for idx in 1 .. 10000 loop
v := rpad('x',32767,'x');
vc(idx) := v;
end loop;
end;
/
ERROR at line 1:
ORA-00600: internal error code, arguments: [723], [41000], [pga heap], [], [],
[], [], []
3. この時、600診断イベントをPGAヒープダンプを実行するように設定すれば、10261→600→ヒープダンプの手順で自動的にPGAヒープダンプが実行されます。
alter system set events '600 trace name heapdump level 0x20000001';
4. 下記は自動的に生成されたPGAヒープダンプの一部です。特に、ダンプレベル0x20000001のおかげで下位Subheapを含んだダンプが記録されます。
DDE: Problem Key 'ORA 600 [723]' was flood controlled (0x2) (incident: 44800)
ORA-00600: internal error code, arguments: [723], [41000], [pga heap], [], [], [], [], []
****** ERROR: PGA size limit exceeded: 102450812 > 102400000 *****
******************************************************
HEAP DUMP heap name="pga heap" desc=11AFB098
extent sz=0x206c alt=92 het=32767 rec=0 flg=2 opc=1
parent=00000000 owner=00000000 nex=00000000 xsz=0xfff8 heap=00000000
fl2=0x60, nex=00000000
EXTENT 0 addr=39150008
Chunk 39150010 sz= 24528 free " "
Chunk 39155fe0 sz= 40992 freeable "koh-kghu call " ds=0D4D9A60
EXTENT 1 addr=39140008
Chunk 39140010 sz= 24528 free " "
Chunk 39145fe0 sz= 40992 freeable "koh-kghu call " ds=0D4D9A60
...
5. 最後の段階はヒープダンプを分析してどんなオブジェクトがヒープを使用しているのかを見破ることです。例えば、私は
ティパックという個人的なライブラリーを使用します。
select * from table(tpack.heap_file_report('C:\oracle\diag\rdbms\ukja1106\ukja1106\trace\ukja1106_ora_3640.trc'));
TYPE HEAP_NAME ITEM ITEM_COUNT ITEM_SIZE HEAP_SIZE RATIO
-------- ---------------- ---------------- ---------- ---------- ---------- ----------
HEAP pga heap 0 97.14 97.14 100
HEAP top call heap 0 .18 .18 100
HEAP top uga heap 0 .31 .31 100
CHUNK pga heap free 1554 36.2 97.1 37.3
CHUNK pga heap recreate 9 0 97.1 0
CHUNK pga heap perm 14 0 97.1 0
CHUNK pga heap freeable 1597 60.7 97.1 62.5
CHUNK top uga heap recreate 1 0 .3 19.9
CHUNK top uga heap free 5 0 .3 0
CHUNK top uga heap freeable 4 .2 .3 79.9
CHUNK top call heap free 3 .1 .1 65.5
CHUNK top call heap recreate 2 0 .1 1
CHUNK top call heap freeable 1 0 .1 33.3
CHUNK top call heap perm 1 0 .1 0
OBJECT pga heap kews sqlstat st 1 0 97.1 0
OBJECT pga heap pesom.c:Proces 3 0 97.1 0
...
6. オラクルの診断イベントのほかに、V$SESSTATビューをモニターリングしながらメモリーサイズがあるサイズを超える時、PGAヒープダンプを行なう方法もあります。例えば、前述の
ティパックライブラリーを次のように利用できます。
col report_id new_value report_id
select tpack_server.create_report('Heap Dump') as report_id from dual;
exec tpack_server.add_parameter('&report_id', 'dump_level', '0x20000001');
exec tpack_server.add_parameter('&report_id', 'get_whole_contents', 0);
exec tpack_server.add_condition('&report_id', 'STAT', 'session pga memory', '>100000000', 'SUM');
exec tpack_server.register_report('&report_id');
-- start server
exec tpack_server.start_server;
PGAヒープサイズが100000000Bに達すると、ティパックはあらかじめ定義されているプロシージャを実行してヒープダンプを落とします。
Fri Jun 11 06:19:10 GMT+00:00 2010 : Session 142 got! sum=659645392, name = session pga memory
...
Fri Jun 11 06:27:50 GMT+00:00 2010 : executing report 1:142:1973827792 for session 142
Fri Jun 11 06:27:55 GMT+00:00 2010 : executing report = begin tpack.heap_dump( dump_level=>'0x20000001', get_whole_contents=>0, session_id => 142); end;
...
10261と600診断イベントは仮の方便にすぎないでしょう。最も重要なのはヒープダンプを注意深く分析してPGAサイズの非正常的な増加を防ぐことです。