2018.04.11
ASSM
目次
ASSM
ASSM(Automatic Segment Space Management)は、FLMとは異なり、フリーリストを使用してのフリーブロックを管理していません。FLMを使用する場合はフリーリスト、フリーリストのグループなどの属性を利用して、管理者が手動(Manual)による管理が可能な反面、ASSMを使用している場合には、さらに、これらの属性をサポートしていない管理者がセグメント領域管理手法を変更することができません。この意味で、すなわち、手動で管理が不可能だという意味での自動化されたセグメント領域管理手法として名前が付けられました。
ASSMで使用されるフリーブロック管理手法は、非常に複雑で、インテリジェントなのものになります。個々の重要な概念と性能の観点から有利な点だけを集中的に調べるものとなります。
フリーブロックの意味
ASSMでのフリーブロックの意味は、FLMのと同じです。つまり、INSERT操作のために使用可能な空きブロックを意味します。しかし、フリーブロックを判断する基準は、新たに定義されて、さらに洗練された方式のブロックスペース管理の概念を使用します。ASSMも、特定のブロックがフリー(Free)状態であるかフル(Full)状態であるかの区別は存在しますが、ブロックがどのような余裕があるかを判断するための新しい基準を使用します。これ余裕状態(Freeness Status。FS)と呼びます。余裕度の状態は、次の4種類の値を持ちます。
・FS1:ブロックの空き容量が0〜25%である状態 ・FS2:ブロックの空き容量が25〜50%である状態 ・FS3:ブロックの空き容量が50〜75%である状態 ・FS4:ブロックの空き容量が75〜100%である状態
ブロックがフリーかどうかは、まずPCTFREE属性の値を用いて判断しますが、フリーブロックがどのように余裕があるかを再度FS値を用いて判断することになります。これにより、Oracleが最大限のブロックを効率的に利用できるように保証します。Oracleは、PCTFREE属性とFS値を利用して、次のような基準でフリーブロックをするかどうかを決定します。
・エクステントが追加で割り当てられている過程で生じたHWMの下に存在している一度も使用されていないブロック。 FLMと同じです。 ・INSERTステートメントによってロー(Row)が追加されたが、まだPCTFREE属性によって指定された領域を使い切っていない ブロック。FLMの場合と同様です。 ・PCTFREE属性によって指定された領域をすべて消費した後、再びDELETEまたはUPDATEによって使用率が低くなるが、FS状態が 変わる場合。FLMはフルブロックがフリーブロックに変わる基準でPCTUSED属性が使用されているのに対し、ASSMはもはや PCTUSED属性が使用されません。ASSMはプールの状態のブロックのデータが削除され、FSの状態が変化しなければなりませんが、 例えばFS1(0〜25%の空き)状態でFS2(25〜50%の空き)状態に変わる場合に再度フリーブロックとして認識されます。 FLMに比べてブロックの使用程度を区分する基準がさらに洗練されたことを知ることができます。
Oracleが提供するDBMS_SPACEパッケージを使用すると、セグメント領域に関するさまざまな情報を得ることができます。特にDBMS_SPACE.SPACE_USAGEプロシージャを使用すると、特定のセグメントのFS1、FS2、FS3、FS4、Full、Unformatted状態のブロック数とサイズ(バイト)の情報を得ることができます。以下は、DBMS_SPACE.SPACE_USAGEプロシージャを使用する簡単な例です。
DECLARE v_unformatted_blocks NUMBER; v_unformatted_bytes NUMBER; v_fs1_blocks NUMBER; v_fs1_bytes NUMBER; v_fs2_blocks NUMBER; v_fs2_bytes NUMBER; v_fs3_blocks NUMBER; v_fs3_bytes NUMBER; v_fs4_blocks NUMBER; v_fs4_bytes NUMBER; v_full_blocks NUMBER; v_full_bytes NUMBER; BEGIN DBMS_SPACE.SPACE_USAGE( segment_owner =>'OWI', segment_name =>'BIG1', segment_type =>'TABLE', unformatted_blocks => v_unformatted_blocks, unformatted_bytes => v_unformatted_bytes, fs1_blocks => v_fs1_blocks, fs1_bytes => v_fs1_bytes, fs2_blocks => v_fs2_blocks, fs2_bytes => v_fs2_bytes, fs3_blocks => v_fs3_blocks, fs3_bytes => v_fs3_bytes, fs4_blocks => v_fs4_blocks, fs4_bytes => v_fs4_bytes, full_blocks => v_full_blocks, full_bytes => v_full_bytes ); DBMS_OUTPUT.PUT_LINE('v_unformatted_blocks = ' || v_unformatted_blocks); DBMS_OUTPUT.PUT_LINE('v_unformatted_bytes = ' || v_unformatted_bytes); DBMS_OUTPUT.PUT_LINE('v_fs1_blocks = ' || v_fs1_blocks); DBMS_OUTPUT.PUT_LINE('v_fs1_bytes = ' || v_fs1_bytes); DBMS_OUTPUT.PUT_LINE('v_fs2_blocks = ' || v_fs2_blocks); DBMS_OUTPUT.PUT_LINE('v_fs2_bytes = ' || v_fs2_bytes); DBMS_OUTPUT.PUT_LINE('v_fs3_blocks = ' || v_fs3_blocks); DBMS_OUTPUT.PUT_LINE('v_fs3_bytes = ' || v_fs3_bytes); DBMS_OUTPUT.PUT_LINE('v_fs4_blocks = ' || v_fs4_blocks); DBMS_OUTPUT.PUT_LINE('v_fs4_bytes = ' || v_fs4_bytes); DBMS_OUTPUT.PUT_LINE('v_full_blocks = ' || v_full_blocks); DBMS_OUTPUT.PUT_LINE('v_full_bytes = ' || v_full_bytes); END; / v_unformatted_blocks = 0 v_unformatted_bytes = 0 v_fs1_blocks = 0 v_fs1_bytes = 0 v_fs2_blocks = 0 v_fs2_bytes = 0 v_fs3_blocks = 0 v_fs3_bytes = 0 v_fs4_blocks = 0 v_fs4_bytes = 0 v_full_blocks = 237 v_full_bytes = 1941504
3段階ビットマップブロック
ASSMを使用するセグメントは、フリーブロックのリストを管理するために、もはやフリーリスト(Freelist)を使用していません。代わりに、3段階のビットマップブロック(Bitmap Block)を利用して、より効率的で立体的にセグメント領域を管理します。
L1BMB(Level1 Bitmap Block)は、各ブロックの余裕も状態(Freeness Status。FS)を管理する役割をします。一つのL1BMBがセグメントのサイズに応じて16〜1024個のブロックの状態を管理します。次の例は、システムの1つのL1BMBをダンプにダウンロードしたもので、合計64個のブロックの状態を管理することを確認することができます。ブロックの状態は「Unformatted、FULL、0-25%free、25-50%free、50-75%free、75-100%free」のいずれかの値になります。
-------------------------------------------------------- DBA Ranges:L1BMBが管理するブロックのリストに -------------------------------------------------------- 0x01804109 Length:64 Offset:0 0:Metadata1:Metadata2:Metadata3:Metadata 4:Metadata5:Metadata6:Metadata7:Metadata 8:Metadata9:Metadata10:Metadata11:Metadata 12:Metadata13:Metadata14:Metadata15:Metadata 16:Metadata17:Metadata18:Metadata19:Metadata 20:Metadata21:Metadata22:FULL23:FULL 24:FULL25:FULL26:FULL27:FULL 28:FULL29:FULL30:FULL31:FULL 32:FULL33:FULL34:FULL35:FULL 36:FULL37:FULL38:FULL39:FULL 40:FULL41:FULL42:FULL43:FULL 44:FULL45:FULL46:FULL47:FULL 48:FULL49:FULL50:FULL51:FULL 52:FULL53:FULL54:FULL55:FULL 56:FULL57:FULL58:FULL59:FULL 60:FULL61:FULL62:FULL63:FULL --------------------------------------------------------
L2BMB(Level2 Bitmap Block)は、L1BMBのリストを管理します。一つのL2BMBが複数のL1BMBを管理することになります。次の例は、単一のL2BMBをダンプにダウンロードしたもので、合計20個のL1BMBを管理していることがわかります。
-------------------------------------------------------- 0x01804109 Free: 1 Inst: 1 0x0180410a Free: 1 Inst: 1 0x0180410b Free: 1 Inst: 1 0x0180410c Free: 1 Inst: 1 0x0180410d Free: 5 Inst: 1 0x0180410e Free: 5 Inst: 1 0x0180410f Free: 5 Inst: 1 0x01804110 Free: 5 Inst: 1 0x01804111 Free: 5 Inst: 1 0x01804112 Free: 5 Inst: 1 0x01804113 Free: 5 Inst: 1 0x01804114 Free: 5 Inst: 1 0x01804115 Free: 5 Inst: 1 0x01804116 Free: 5 Inst: 1 0x01804117 Free: 5 Inst: 1 0x01804118 Free: 5 Inst: 1 0x01804119 Free: 5 Inst: 1 0x0180411a Free: 5 Inst: 1 0x0180411b Free: 5 Inst: 1 0x0180411c Free: 5 Inst: 1 --------------------------------------------------------
L2BMBはL1BMBに対して次のような情報を管理します。
・L1BMB DBA ・L1BMBが管理するブロックの最大余裕度(Maximum Freeness)。1= Full、2 = FS1、3 = FS2、4 = FS3、 5= FS4を意味します。 Oracleは、空間の効率性を高めるために最も余裕度が高いL1BMBを最初に使用します。 ・所有インスタンス(Owning Instance)。RAC環境では、L1BMBを所有してインスタンスの数を意味します。 RAC環境では、この情報を利用して、インスタンス間でフリーブロックをめぐる競合を最小限に抑えています。 ASSMでフリーリストグループ(Freelist Group)の機能が消えた理由がここにあります。
L3BMBはL2BMBのリストを管理します。一つのL3BMBが複数のL2BMBを管理することができます。L3BMBは、ほとんどの場合、別の物理的なブロックに存在せず、セグメントヘッダブロックの内部に存在します。セグメントのサイズが非常に大きく、単一のL3BMBで管理が不可能にのみ、別のL3BMBが物理的に分離されます。次の例は、L3BMB(セグメントヘッダ)をダンプにダウンロードしたもので、L2BMBの付加的な情報(L2 Hint for inserts)とL2BMBのDBA値を確認することができます。
Segment Type: 1 nl2: 1 blksz: 8192 fbsz: 0 L2 Array start offset: 0x00001434 First Level 3 BMB: 0x00000000 L2 Hint for inserts: 0x0180411d Last Level 1 BMB: 0x0180411c Last Level II BMB: 0x0180411d Last Level III BMB: 0x00000000 … Second Level Bitmap block DBAs -------------------------------------------------------- DBA 1: 0x0180411d
OracleはL3BMB、L2BMB、L1BMBを順次移動しながら、新しいデータを追加する最も理想的なフリーブロックを探します。ASSMで使用する3段階のビットマップブロック構造は、以前フリーリスト構造に比べてかなり柔軟で自動化されていて、FLMを使用するときのような外部的なチューニングや設定が不要です。パフォーマンスもよくチューニングされたFLMを使用する場合とほぼ同じです。ただし、大量のDMLが発生する場合には、ビットマップブロックを管理するためのオーバーヘッドが発生するため、これによる若干のパフォーマンスの低下が発生することがあります。
RACとASSM
ASSMはRACのためのセグメント管理手法といっても過言ではないほどRAC環境に最適化されています。ASSMが提供する次のような特徴を見ると、OracleはRACに最適化されたセグメントの管理手法を提供するために努力した跡を見つけることができるのです。
・L1BMBのリソース親和性:L1BMBが最初に作成されるときにRACシステムのいずれかのインスタンスが、 このブロックの所有権を持つかどうかを決定します。つまりL1BMBは、リソースに優しい度を持つように 設計されました。別のインスタンスは、異なるL1BMBを使用するため、フリーブロックをめぐる競合が 最小限に抑えられます。 FLMでのフリーリストのグループ機能とほぼ同様の効果を提供することにあります。 フリーリストのグループ機能は、受動的な設定が必要で、クラスタのメンバーが変わる状況について適応が 非常に低いという点を考慮すると、ASSMの優秀性を実現するものとなります。 ・L1BMB窃盗動作:L1BMBは、リソースに親和性を持っているので、特定のインスタンスに属することになります。 これは、一般的に望ましい機能ですが、もし特定のインスタンスが、特定のL1BMBを継続して占有する場合、 データの非対称(Data Skew)現象が起こることがあります。データ非対称とは、特定のインスタンスが セグメントの特定の部分を独占することで、他のインスタンスがその部分を全く使用することができなく なる現象を意味します。FLMからフリーリストグループを使用している場合は、データの非対称現象が 発生することができるということは、前述しています。ASSMは、データの非対称現象を根本的に回避する ためにL1BMB窃盗動作(BMB Stealing)機能を提供します。 L1BMB Stealing機能は、文字通り、 他のインスタンスが所有するL1BMBを盗んで使用する機能を言います。Oracleは、セグメント領域の 使用要求の程度が過度に多いと判断されると、他のインスタンスが所有するL1BMBを盗んで使用します。 特定のインスタンスがクラスタから抜けた場合でも、そのインスタンスが所有するL1BMBは、 他のインスタンスによって盗まれます。厳しいリソース親和性ではなく、必要に応じて所有インスタンスが 変わることができるという意味で、これらの機能を約親和性(Soft Affinity)と呼ぶこともあります。 つまりL1BMBは約親和性を有し、これにより、FLMの問題となったデータの歪みを根本的に防止するのです。
ASSMの空間管理は、RACシステムでは、各ノードの処理能力を最大限に引き出すことができます。
ASSMとFBロック競合
ASSMを使用するセグメントの大量DML操作時にFBロック競合が発生する場合がしばしばあります。FBロックはFormatting Block Lockを意味します。FBロックの意味を理解するには、ASSMを使用しているセグメントは、二つのHWM(High Water Mark)が存在するという事実を理解する必要があります。
ASSMでは、1つのエクステントが複数のL1BMBによって分けて管理することができます。もし、特定のエクステントの前の部分と後の部分はL1BMBによって管理され、中間部分はまだL1BMBが割り当てられていない場合、中間の穴(Hole)が生じることになります。すなわち、セグメントの途中でまったく使用されていない非フォーマット状態のブロックが多数存在することになるのです。このような現象は、FLMでは見られないASSMだけの固有な領域の管理手法によってもたらされます。これらの理由から、Oracleは、Low HWMとHigh HWMという二つのHWMを管理します。Low HWM以下のブロックはすべてのフォーマット状態のブロックで「現在使用中」であるブロックです。High HWM以上のブロックは、すべての非フォーマット状態のブロックであり、「まだ使用されていない」ブロックでです。Low HWMとHigh HWMの間には、まだ使用されていない非フォーマット状態のブロックが存在することになります。これらの非フォーマット状態のブロックは、後日INSERT操作で使用される時にフォーマットされ、この過程でFBロックを獲得します。多くのプロセスが同時に同じ領域の非フォーマットブロックを使用する場合FBロック競合が発生することになり、enq:FB – contentionイベントの待機が観察されます。FBロック競合はASSM環境では避けられない現象であり、性能に与える影響もわずかです。以下のサンプルでは、セグメントヘッダブロックのダンプファイルにセグメントヘッダブロック内でLow HWMとHigh HWMを共に管理することを確認することができます。
Start dump data blocks tsn: 7 file#: 6 minblk 16670 maxblk 16673 buffer tsn: 7 rdba: 0x0180411e (6/16670) scn: 0x0000.00472a3d seq: 0x01 flg: 0x04 tail: 0x2a3d2301 frmt: 0x02 chkval: 0x7e6e type: 0x23=PAGETABLE SEGMENT HEADER Hex dump of block: st=0, typ_found=1 … Extent Control Header ----------------------------------------------------------------- Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 1280 last map 0x00000000 #maps: 0 offset: 2716 Highwater:: 0x0180420c ext#: 0 blk#: 259 ext size: 1280 #blocks in seg. hdr's freelists: 0 #blocks below: 259 mapblk 0x00000000 offset: 0 Unlocked -------------------------------------------------------- Low HighWater Mark : Highwater:: 0x0180420c ext#: 0 blk#: 259 ext size: 1280 #blocks in seg. hdr's freelists: 0 #blocks below: 259 mapblk 0x00000000 offset: 0 Level 1 BMB for High HWM block: 0x0180410d Level 1 BMB for Low HWM block: 0x0180410d …
次のスクリプトは、ASSMを使用するセグメントについて、同時多発的な大量INSERT操作を実行する場合にどのような種類の競合が発生するかをテストした結果、HWロック競合、バッファロック競合、FBロック競合などが主に目撃されていることを知ることができます。
- ASSMを使用する表スペースの作成 create tablespace fb_tbs1 datafile「/home/oracle/oradata/10gr2/ORA102/fb_tbs1.dbf」size 10M autoextend on segment space management auto extent management local uniform size 5M - テーブルの作成(1ロー= 1ブロック) create table fb_table1(id number、 name1 char(2000)default 'a'、 name2 char(2000)default 'a'、 name3 char(2000)default 'a'、 name4 char(1500)default 'a') tablespace fb_tbs1; - FB_TABLE1に500件を追加する手順 create or replace procedure fb_insert is begin for idx in 1 .. 500 loop insert into fb_table1(id)values(idx); end loop; end; - 同時に20個のセッションでは、SQL * Traceを有効にした状態でFB_INSERTプロシージャを実行して、 trcsessツールを利用して、20個のセッションが残したトレースファイルをマージした後、 tkprofツールを利用して待機回数と時間情報抽出結果は、次のとおりです。 INSERT INTO FB_TABLE1(ID) VALUES (:B1) Call count cpu elapsed disk query current rows ----- ------ ----- ------ ----- ---- ------ ---- Parse 21 0.00 0.02 0 0 0 0 Execute 10500 17.22 605.20 0 20176 100188 10500 Fetch 0 0.00 0.00 0 0 0 0 ------ ------ ----- ------ ----- ---- ------ ---- Total 10521 17.22 605.22 0 20176 100188 10500 Misses in library cache during parse:1 Misses in library cache during execute:1 Optimizer mode:ALL_ROWS Parsing user id:55(recursive depth:1) Elapsed times include waiting on following events: Wait Event Total Total Time Waited Timeout Waited ------------------------------ ------- ------- ------ - enq:HW? contention 1364 2.82 348.29 latch:In memory undo latch 4 0.00 0.00 enq:FB? contention 1692 0.17 9.71 buffer busy waits 9276 0.29 100.79 latch:redo copy 522 0.14 1.68 latch free 108 0.01 0.41 latch:cache buffers chains 359 0.22 2.06 enq:TX? contention 270 2.63 4.07 log buffer space 656 0.29 55.26 latch:redo allocation 20 0.00 0.02 latch:enqueue hash chains 74 0.09 1.61 wait list latch free 9 0.02 0.21 cursor:pin S 9797 0.00 0.00 latch:undo global data 11 0.02 0.09 ...
HWロック競合は、セグメントの拡張に応じてHWMを移動する過程で発生すると、enq:HW – contention待機イベントで観察されます。FBロック競合はLow HWMとHigh HWMの間の穴(Hole)に対応するブロックをフォーマットする過程で発生しenq:FB – contentionイベント待機中に観察されます。バッファロック競合はブロックの余裕も状態の変更により、ビットマップブロックの情報を変更する過程で発生し、ブロッククラスの値が8または9のbuffer busy waitsイベント待機で観察されます。FLMを使用する場合には、FREELISTS属性やFREELIST GROUPS属性、あるいは_BUMP_HIGHWATER_MARK_COUNTパラメータの値を変更することにより、これらの競合者のチューニングが可能でしたが、ASSMは、これらの外部的なチューニングを行うことができません。したがって、問題が発生した原因に基づいて、アプリケーションの動作を改善する方法のチューニングのアプローチに従うほかないのです