ASSMに関する検証 その1

投稿日: 2007年3月14日

<ASSMに関する検証 その1>
ペンネーム: サマー・リーフ

今回から9iR1から機能追加された、自動セグメント領域管理(ASSM:Auto
Segment Space Management)について取り上げていってみます。

▼はじめに

本検証では、異なるセグメント領域管理方法でどのように内部動作をしている
か確認し、トランザクション環境によってどちらを選択すべきか参考になるよ
うに確認&検証を進めたいと思います。

▼そもそも、セグメント領域管理とは

Oracle内部では、セグメントヘッダーにセグメントの使用ブロックの空き状態
を管理します。分かりやすく説明すると、セグメントに対して新しい行を
INSERTできるブロックはどのブロックか?、管理するという事です。
これは、表領域を効率的に再利用する為に制御する仕組みです。

▼セグメント領域管理の種類

セグメント領域管理方法は、FREELIST管理と自動セグメント領域管理の2種類
の管理方法があります。(9iR1以降)

▼セグメント領域管理(FREELIST管理、自動セグメント領域管理)の詳細を次
にまとめます。

1.FREELIST管理

10gR1まで、ローカル管理の表領域作成時のデフォルト設定となります。
従来通り、 FREELIST でセグメントブロックの空き領域を管理します。
セグメント作成時に storage句を指定して pctfree や pctusedの値を調整
し FREELIST へのエントリーを制御しいます。
例えば行のINSERT時の動作において、ブロックに pctfree で指定した割合
以上の空きがある場合、INSERT可能対象ブロックとして FREELIST にエント
リーされます。行のINSERT時は、FREELISTにエントリーされた空きブロック
を検索して INSERT可能ブロックに行が格納されます。
また順次に空きブロックを検索する為、一度に一つしかブロックアクセスが
出来ません。複数の DMLが同時実行された場合、セグメントヘッダの競合が
発生します。
それを避けるためにfreelists の値を調整するなどなど苦労した DBA の方
々もいるのではないでしょうか。

2.自動セグメント領域管理

9iR1から機能追加され 通称 ASSM と呼ばれる領域管理方法です。
この機能は、OLTPなどの同時実行SQL(INSERT)のパフォーマンスを向上させ
るための機能です。10gR2から、ローカル管理の表領域作成時のデフォルト
設定となります。Oracle内部で、セグメントが自動的に調整されビットマッ
プでセグメントブロックの空き領域を管理します。従来、セグメント作成時
にstorage句で指定可能だったpctused,freelists,freelists_groupsは無効と
なり、指定したとしても無視されます。領域管理に使用されるビットマップ
は4ビットで表現されたブロックの状態(下記参照)を保持します。

値    説明
------ ---------------
0000   未フォーマット
0001   空きなし
0010   空きが25%
0011   空きが25%~50%
0100   空きが50%~75%
0101   空きが75%以上

FREELIST管理と大きく異なるのは、空きブロックを順次検索する必要が無く
ビットマップの異なる部分を同時に使用できる事です。
また、Bツリー索引に似た構造でLevel分け(3Level)され空きブロックに対
し高速にアクセスが可能であることです。

従来のFREELIST管理では、大量のINSERT文が同時に実行されるような環境に
おいて、空きブロックに同時アクセスが集中しセグメントヘッダーの競合が
発生するケースあります。原因の多くはFREELISTの値設定が不適切であるこ
とが多いのですが・・・。
これらは、自動セグメント領域管理にすることで、軽減できます。

※ちょっとここでブレイク!※
[Oracleのバージョンによる違い]
・10gR1までは、ローカル管理の表領域作成時にSEGMENT SPACE MANAGEMENT句
にて明示的に”AUTO”(自動セグメント領域管理)とオプション指定しないと
ASSM が有効になりませんでした。
・10gR2以降は、ローカル管理の表領域を作成するとデフォルトでSEGMENT SPACE
MANAGEMENT句が、”AUTO”(自動セグメント領域管理)となり ASSM が有効と
なります。
従って 10gR2以降、従来のFREELIST管理にするには SEGMENT SPACE MANAGEMENT
句に”MANUAL”(FREELIST管理)とオプション指定する必要があります。

では、さっそく、セグメント領域管理(FREELIST管理、自動セグメント領域管理)
の違いを見ていきましょう。

■環境

OS:WindowsXP
DB:Oracle10g EE Release 10.2.0.3

■表領域作成

表領域作成時に、SEGMENT SPACE MANAGEMENT句でセグメント領域管理方法を
指定します。

自動セグメント領域管理

CREATE TABLESPACE TBS_ASSM_AUTO
DATAFILE
'C:oracleproduct10.2.0oradataorclTBS_ASSM_AUTO.dbf' SIZE 100M
SEGMENT SPACE MANAGEMENT AUTO;

FREELIST管理

CREATE TABLESPACE TBS_ASSM_MANUAL
DATAFILE
'C:oracleproduct10.2.0oradataorclTBS_ASSM_MANUAL.dbf' SIZE 100M
SEGMENT SPACE MANAGEMENT MANUAL;

作成表領域の情報

DBA_TABLESPACESディクショナリのSEGMENT_SPACE_MANAGEMENT列を確認します。

  TS#  FILE# NAME               EXTENT_MAN SEGMENT_SPACE_MANAGEMENT
----- ------ ------------------ ---------- -------------------------
    9      7 TBS_ASSM_AUTO      LOCAL      AUTO
   10      8 TBS_ASSM_MANUAL    LOCAL      MANUAL

■ユーザーのデフォルト表領域変更

alter user ITI1 default tablespace TBS_ASSM_AUTO;
alter user ITI2 default tablespace TBS_ASSM_MANUAL;

■各ユーザーにおいて表作成(中身は空っぽ)

connect ITI1/***;
create table SUMMER_LEAF(col1 char(10),col2 date);
connect ITI2/***
create table SUMMER_LEAF(col1 char(10),col2 date);

▼セグメント領域管理(FREELIST管理、自動セグメント領域管理)の違い

まずは、構造の違いから確認します。ディクショナリを見てみると・・・・
ITI1スキーマのセグメントは、PCT_USED、FREELISTSに値が入ってないのが
分かります。指定してセグメントを作成しても無視されます。

OWNER    TABLE_NAME    TABLESPACE_NAME      PCT_FREE   PCT_USED  FREELISTS
-------- ------------- ------------------ ---------- ---------- ----------
ITI1     SUMMER_LEAF   TBS_ASSM_AUTO             10
ITI2     SUMMER_LEAF   TBS_ASSM_MANUAL           10         40          1

この際、セグメントヘッダーのダンプも取得しておきます。何か”違い”が
わかるやもしれません。ダンプを出力するには、セグメントが作成されてい
る表領域のデータファイル番号、ブロック番号が必要でしたね。

OWNER SEGMENT_NAME HEADER_FILE HEADER_BLOCK
——– ———————- ———– ————
ITI1 SUMMER_LEAF 7 27
ITI2 SUMMER_LEAF 8 25

セグメントヘッダーダンプ取得(自動セグメント領域管理)

alter system dump datafile 7 block 27;

セグメントヘッダーダンプ抜粋(自動セグメント領域管理)
なにやら、期待通りの複雑怪奇!?なものが出てきました。

  ↓ここから↓
  ********************************************************************
    Extent Control Header
  -----------------------------------------------------------------
  Extent Header:: spare1: 0      spare2: 0      #extents: 1      #blocks: 8
                  last map  0x00000000  #maps: 0      offset: 2716  
      Highwater::  0x01c00021  ext#: 0      blk#: 8      ext size: 8
  #blocks in seg. hdr's freelists: 0     
  #blocks below: 5     
  mapblk  0x00000000  offset: 0     
                   Unlocked
  --------------------------------------------------------
  Low HighWater Mark : 
      Highwater::  0x01c00021  ext#: 0      blk#: 8      ext size: 8
  #blocks in seg. hdr's freelists: 0     
  #blocks below: 5     
  mapblk  0x00000000  offset: 0     
1)Level 1 BMB for High HWM block: 0x01c00019
2)Level 1 BMB for Low  HWM block: 0x01c00019
  --------------------------------------------------------
  Segment Type: 1 nl2: 1      blksz: 8192   fbsz: 0      
  L2 Array start offset:  0x00001434
  First Level 3 BMB:  0x00000000
  L2 Hint for inserts:  0x01c0001a
3)Last Level 1   BMB:0x01c00019
4)Last Level II  BMB:0x01c0001a
5)Last Level III BMB:0x00000000
     Map Header:: next  0x00000000 #extents: 1 obj#: 49230 flag: 0x10000000
  Inc # 0 
  Extent Map
  -----------------------------------------------------------------
   0x01c00019  length: 8     
  Auxillary Map
  --------------------------------------------------------
   Extent 0     :  L1 dba:  0x01c00019 Data dba:  0x01c0001c
  --------------------------------------------------------
  
   Second Level Bitmap block DBAs 
   --------------------------------------------------------
   DBA 1:   0x01c0001a
  ********************************************************************
  ↑ここまで↑

同様に、セグメントヘッダーダンプも取得(FREELIST管理)しておきます

alter system dump datafile 8 block 25;

こちらも期待通りです。
セグメントヘッダーダンプ抜粋(FREELIST管理)

[/bash]
↓ここから↓
********************************************************************
Extent Control Header
—————————————————————–
Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 7
last map 0x00000000 #maps: 0 offset: 4128
Highwater:: 0x0200001b ext#: 0 blk#: 1 ext size: 7
#blocks in seg. hdr’s freelists: 1
#blocks below: 1
mapblk 0x00000000 offset: 0
Unlocked
Map Header:: next 0x00000000 #extents: 1 obj#: 49236 flag: 0x40000000
Extent Map
—————————————————————–
0x0200001a length: 7

nfl = 1, nfb = 1 typ = 1 nxf = 0 ccnt = 1
SEG LST:: flg: USED lhd: 0x0200001a ltl: 0x0200001a
********************************************************************
↑ここまで↑

▼よって~したがって~・・・明らかに違う!!と思う点を列挙します。

1.自動セグメント領域管理では、1種類の高水位標(HWM)を保持している。

Level2のビットマップブロック配下には、複数のLevel1のビットマップブロ
ックが作成される階層構造になります。
複数作成された場合、ポインターが、HighまたはLow HWM として管理されま
す。上記のダンプ取得時は、1対1でビットマップブロックが作成されてい
る為、High,Low 共に同じポインターで管理されています。

セグメントヘッダーダンプ抜粋(自動セグメント領域管理)に追記した番号
1) ~ 2)をみると HighまたはLow HWM がどのブロックを示しているか分か
ります。

1)Level 1 BMB for High HWM block: 0x01c00019
⇒下2桁の16進数を10進数にすると 25番目のブロック。
2)Level 1 BMB for Low HWM block: 0x01c00019
⇒下2桁の16進数を10進数にすると 25番目のブロック。

2.自動セグメント領域管理では、Level分けされたビットマップのポインター
を保持している。

セグメントヘッダーダンプ抜粋(自動セグメント領域管理)に追記した番号
3) ~ 5) をみると何番目のブロックが、どのLevelのビットマップブロック
を示しているか分かります。

3)Last Level 1 BMB:0x01c00019
⇒下2桁の16進数を10進数にすると 25番目のブロック。
4)Last Level II BMB:0x01c0001a
⇒下2桁の16進数を10進数にすると 26番目のブロック。
5)ast Level III BMB:0x00000000
⇒下2桁の16進数は、”00″なので Level3のビットマップブロックなし。

3.空きブロックの数が異なっている。

自動セグメント管理では、空きが 5ブロック + Level1~3 のビットマップ
ブロックで、合計8ブロックを使用しています。
FREELIST管理では、空きが 1ブロック + FREELISTマップが 1ブロックと
合計2ブロックを使用しているように見えます。

ん? 初期エクステントが、両方とも 8 ブロックのはずなのに、空きブロッ
クのエントリ数が異なっています。

DBA_EXTENTSを参照すると、25ブロック目から 8ブロック確保していること
が分かります。

OWNER       FILE_ID   BLOCK_ID     BLOCKS SEGMENT_TYPE  SEGMENT_NAME
-------- ---------- ---------- ---------- ------------- --------------
ITI1             7         25          8   TABLE         SUMMER_LEAF
ITI2             8         25          8   TABLE         SUMMER_LEAF

どうも自動セグメント領域管理の場合は、確保したエクステントの中のブロ
ックの使用状態を保持し空きブロックと管理するようです。
逆に、FREELIST管理では、実際に行が格納されていないブロックは空きブロ
ックではなく未使用ブロックとして管理するようです。

んんーーーー、なんだか難しい事をわかったように書き下ろしましたが・・。
Level分けされたビットマップとか、High, Low HWMなどなど、今後ポイントと
なりそうなキーワードが出てきました。

まず今回は、セグメント領域管理(FREELIST管理、自動セグメント領域管理)
の違いをさくっと確認しました。次回以降、これらを”どっぷり掘り下げたい
!!”と思います

北日本では、80cmもの大雪が降ったようです。
パウダースノーが恋しい今日この頃 茅ヶ崎にて