ローカルエクステントマネージメントに関する検証 その3
<ローカルエクステントマネージメントに関する検証 その3>
ペンネーム ちゃむ
————————————————————————–
8iからの新機能ローカルエクステントマネージメントを以下「LOCAL」と呼ぶ。
従来のデータディクショナリーでエクステントを管理する方法を以下「DICTIONARY」
と呼ぶ。
————————————————————————–
前回は、実際に「LOCAL」がビットマップ管理している様子を見てきた。
今回は、「LOCAL」で管理されている領域に対して、実際にオブジェクトを作成
した時の、ビットマップ情報の変化について見てみよう。
以下に紹介するすべての検証結果は、DB_BLOCK_SIZE = 2Kで行ったものである。
「LOCAL」を作成する
CREATE TABLESPACE tbs_u_1 DATAFILE 'c:tbs_u_1.ora' SIZE 1024k EXTENT MANAGEMENT LOCAL UNIFORM SIZE 8K;
作成直後のDBA_FREE_SPACEの様子
TABLESPACE_NAME FILE_ID BLOCK_ID BYTES BLOCKS -------------------------------------------------- TBS_U_1 25 33 983040 480
この状態で、以下のようなテーブルを作成してみよう。
このテーブルは、空領域のすべて(960K(983040))を使い切らせるためのも
のである。
CREATE TABLE tbs_u_1_tbl (col number) storage (initial 960k next 2k minextents 1 pctincrease 0) tablespace tbs_u_1;
このときのブロックダンプは?
ALTER SYSTEM DUMP DATAFILE 25 BLOCK 3;
File Space Bitmap Block: BitMap Control: RelFno: 25, BeginBlock: 33, Flag: 0, First: 120, Free: 14216 FFFFFFFFFFFFFFFF FFFFFFFFFFFFFF00 0000000000000000 0000000000000000 1行目 0000000000000000 0000000000000000 0000000000000000 0000000000000000 2行目 0000000000000000 0000000000000000 0000000000000000 0000000000000000 3行目 : : : : : : (途中省略) : : : : : : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 54行目 0000000000000000 0000000000000000 0000000000000000 0000000000000000 55行目 0000000000000000 0000000000000000 0000000000000000 0000000000000000 56行目 End dump data blocks tsn: 36 file#: 25 minblk 3 maxblk 3
予想どおり、16進数で表わされているビットマップ情報に変化が生じた。
(テーブルを作成する前は、すべて 0 であった)
そもそも、このビットマップ情報は、テーブルスペースtbs_u_1の場合、480ブ
ロック分(983040 / 2048)の「使用」および「未使用」の状態を表わせなけれ
ばならない。
上記のダンプの状態を考察してみよう。
1.16進数一桁で表現できる状態の数は4ビットなので「4」通り
(1つのビットで「使用」「未使用」を表している)
2.領域を確保していく単位は、UNIFORM SIZE 8K(4ブロック)
この場合、「4」ブロックを1つの塊(単位)として、1ビットで「使用」
「未使用」を表すことになる
3.上記ダンプ中の F の数 → 「30」個
上記の1、2,3の「」で括られた数字を掛け合わせると、4×4×30=480になる。
これは、始めにテーブルスペースを作成した直後の未使用ブロック数、つまりtbs
_u_1_tblの総使用可能領域と一致する。
ダンプ中の16進数一桁で、4つの状態×4ブロック単位=16ブロック分のステータス
(使用/未使用)を表現することができる。
その16進数が30個あるので、16ブロック分×30個=480ブロック分という訳である。
したがって、このテーブルスペースtbs_u_1は、480ブロック分の「使用領域」また
は「未使用領域」であるという判断を、30桁分の16進数を用いて管理しているとい
うことだ。
ビットマップ管理されている領域の「0000000000000000」の16進数の列は、
16ブロック(16進数一桁で表現できる状態のブロック数)×16( 0 の数)= 256通り
の状態を表現できる。この「0000000000000000」が、1ブロック中に
4(列の数)× 56(行の数)=224 セット存在している。つまり、1ブロックで
224×256=57344ブロック分の「使用」および「未使用」の状態を表現できる計算
になる。さらに、このビットマップ管理している情報は、前回の結果から
block_id=3からblock_id=32の30ブロック存在していた。
つまり、理論上、全部で、57344*30=1720320ブロック(3440640k)の「使用」お
よび「未使用」領域の状態を管理できることになる。
では、SIZEが少し大き目の「LOCAL」を作成してみよう。
以下のテーブルスペース中、32ブロック分はビットマップ管理などに使用され
ることから、実質105600ブロックが未使用領域として確保されるはずである。
211264K / 2K(ブロック・サイズ) – 32(管理領域) = 105600
CREATE TABLESPACE tbs_u_1_b1 DATAFILE 'd:tbs_u_1.ora' SIZE 211264k EXTENT MANAGEMENT LOCAL UNIFORM SIZE 8K;
作成直後のDBA_FREE_SPACEの様子
TABLESPACE_NAME FILE_ID BLOCK_ID BYTES BLOCKS ----------------------------------------------------- TBS_U_1_B1 28 33 117440512 57344 TBS_U_1_B1 28 57377 98828288 48256
おや!オヤ!OYA!、なんで2行出力されているんだ。
57344+48256=105600ブロックだから使用できる空領域は予定どおりだけど・・・
あれ!アレ!ARE!、しかも、1行目のBLOCKS=57344・・・なんか見たことがある
数値だぞ!!
これは、さっき計算したビットマップ情報の入っている1ブロックで表わせる
「使用」および「未使用領域」の数だ。
まさか、この表示のされ方。57344ブロックまでのエクステントしか確保できな
いのであろうか?
念のため、60000ブロックを使用するテーブルを作成できるか試してみよう。
CREATE TABLE tbs_u_1_b1_tbl (col number) storage (initial 120000k next 2k minextents 1 pctincrease 0) tablespace tbs_u_1_b1;
よかった、正常に作られた。
テーブル作成直後のDBA_FREE_SPACEの様子は?
TABLESPACE_NAME FILE_ID BLOCK_ID BYTES BLOCKS ----------------------------------------------------- TBS_U_1_B1 28 60093 93265920 45540 テーブルで使用したエクステント (60000ブロック) + 上記の未使用ブロック (45540ブロック) --------------------------------------------------- 始めの未使用ブロック (105600ブロック)
ぜんぜん問題ないようだ。
では、なぜ、空ブロックが2行表示されてしまうのだろうか?
これは、DBA_FREE_SPACEビュー自体の問題であろう。
以下にDBA_FREE_SPACEビューの定義を示す。
union all 以下のselect 文が「LOCAL」の未使用領域を示すための文である。
(ts.bitmapped 0のところから判断できる。)
ちなみに、union allより上の部分は?DICTIONARY」の未使用領域を示すため
の文である。
(ts.bitmapped = 0のところから判断できる)
create or replace view DBA_FREE_SPACE (TABLESPACE_NAME, FILE_ID, BLOCK_ID, BYTES, BLOCKS, RELATIVE_FNO) as select ts.name, fi.file#, f.block#, f.length * ts.blocksize, f.length, f.file# >from sys.ts$ ts, sys.fet$ f, sys.file$ fi where ts.ts# = f.ts# and f.ts# = fi.ts# and f.file# = fi.relfile# and ts.bitmapped = 0 union all select /*+ ordered use_nl(f) use_nl(fi) */ ts.name, fi.file#, f.ktfbfebno, f.ktfbfeblks * ts.blocksize, f.ktfbfeblks, f.ktfbfefno >from sys.ts$ ts, sys.x$ktfbfe f, sys.file$ fi where ts.ts# = f.ktfbfetsn and f.ktfbfetsn = fi.ts# and f.ktfbfefno = fi.relfile# and ts.bitmapped 0 and ts.online$ in (1,4) and ts.contents$ = 0
ここで、from句の元データの違いに注目しよう。
「LOCAL」はx$ktfbfeを元データとしている。
x$ktfbfeを直接見ると、以下のようになる。
DBA_FREE_SPACEは、以下の内容をそのまま出力しているからであろう。
INDX INST_ID KTFBFETSN KTFBFEFNO KTFBFEBNO KTFBFEBLKS ---------------------------------------------------------- 1 1 56 28 33 57344 2 1 56 28 57377 48256
じゃあなんで、x$ktfbfeはこんなデータの入り方をしているのかって言われたら
困ってしまうが、あえて言うならば、「これが仕様です!!」ってなってしまう。
以上 烏帽子岩が遠くに見える 茅ヶ崎にて