Oracle9iに関する検証 その12
<Oracle 9iに関する検証 その12>
ペンネーム ちょびひげ
— ゴメンナサイ編 --
オブジェクトIDとは?
Oracleのオブジェクトを一意に認識する為の番号である。
前回まで検証を行なってきた、データベース・バッファ(以下、バッファ)上
のオブジェクトを見るためのX$BH表にもオブジェクトを一意に認識する為の列
が存在している。
バッファの検証では幾度となく以下のようなSQL文を発行してきた。
SQL> select 2 o.object_name, blsiz , count(*) blocks , lru_flag , tch, state 3 from x$bh b , dba_objects o 4 where b.obj = o.object_id 5 and o.object_name in ('BLOCK4','BLOCK4_IDX') 6 group by b.blsiz, o.object_name, lru_flag, tch, state;
実は上記のSQL文には間違いがある。
と堂々と言えることでは有りませんが。。(申し訳ありません)
例えば以下のようなテーブルとインデックスが存在する。
# 最初がSUMMERで始まるオブジェクトを検索
SQL> select object_id, data_object_id, object_name from dba_objects 2 where object_name like 'SUMMER%'; OBJECT_ID DATA_OBJECT_ID OBJECT_NAME ---------- -------------- -------------------- 43064 43064 SUMMER 43065 43065 SUMMER_IDX
SUMMER_IDXはSUMMERテーブルに張ってあるINDEXである。
OBJECT_IDとDATA_OBJECT_IDとも同じ値であることが分かる。
もちろんバッファ上の該当するオブジェクト番号も同じ値である。
SQL> select obj, count(1) from x$bh 2 where obj in (43064,43065,43066,43067) 3 group by obj; OBJ COUNT(1) ---------- ---------- 43064 16 43065 21
※OBJの条件に先ほど調べたオブジェクト番号と他2つを指定している。
この2つ(43066、43067)に関しては後述する
では、このオブジェクト(SUMMER)をTRUNCATEして、オブジェクト番号がどの
ように変化するかを見てみよう。
SQL> truncate table summer; 表が切り捨てられました。 SQL> select object_id, data_object_id, object_name from dba_objects 2 where object_name like 'SUMMER%'; OBJECT_ID DATA_OBJECT_ID OBJECT_NAME ---------- -------------- -------------------- 43064 43067 SUMMER 43065 43066 SUMMER_IDX
テーブルのTRUNCATEを行うことによって、TRUNCATEしたテーブルはもちろんで
あるが、テーブルに張ってあるインデックスのDATA_OBJET_IDも変わっている
ことが分かる。
ちなみにDATA_OBJECT_IDはオブジェクトのバージョンを管理する為のIDであり、
TRUNCATEを行なうたびに番号が上がっていく。振り当てられる番号は使用され
た最大の番号(OBJECT_IDもしくはDATA_OBJECT_ID)+1である。
TRUNCATEを行なうとディクショナリの変更を行うが、実際のデータの削除は行
なわれないので、当然、ROLLBACKやREDOの情報がテーブル内の各行に対して作
成されない。そのため、データ件数が多い場合は高速であるが、古いデータを
削除するわけではないので、このようなバージョン管理が必要になってくるの
だろう。X$BH表のOBJ列はこのDATA_OBJ_IDをさしている。
面白いのはインデックスのDATA_OBJECT_IDの方が小さくなっている。内部的に
はインデックスのTRUNCATE後にテーブルをTRUNCATEしているのであろう。
また、パッケージなどはバージョンを管理する必要が無いので、DATA_OBJ_ID
列はNULL値であることが分かる。
SQL> select object_name, object_id, data_object_id, object_type from dba_objects 2 where object_type='PACKAGE' OBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE ------------------------------ ---------- -------------- ------------------ HTTP_EXP 19168 PACKAGE HTTP_SECURITY_CASCADE 19150 PACKAGE IFR_EXP 19169 PACKAGE IFR_PACKAGE 19082 PACKAGE INITJVMAUX 5214 PACKAGE IST_ENGINE90 23788 PACKAGE ・ ・
ちなみに、OBJECT_IDはDROPされない限り変わることは無い。
では最後に、TRUNCATE後のバッファの状態も見てみよう。
SQL> select obj, count(1) from x$bh 2 where obj in (43064,43065,43066,43067) 3 group by obj; OBJ COUNT(1) ---------- ---------- 43066 1 43067 3
先程調べたDBA_OBJECT表のOBJECT_ID列の値ではなく、DATA_OBJECT_IDの値で
あることが分かる。SQL文のOBJの条件に2つ(43066、43067)を指定している
のは、DATA_OBJ_IDが1加算されることを予測した仕掛けである。
以上、茅ヶ崎にて