2012年9月11日火曜日

INITIAL_EXTENTと遅延セグメント作成な話4


前回でスッキリ!したのですが、まだちょっと気になるので、dumpを取得してみます。
やってみてがモットーのブログですしね。


では、やってきます。

SQL> create tablespace test_ext2 datafile 'C:\app\oracle\oradata\orcl\test_ext2_01.dbf' size 81K;

表領域が作成されました。

SQL> select TABLESPACE_NAME,BLOCK_ID,BYTES,BLOCKS from dba_free_space where tablespace_name= 'TEST_EXT2';

TABLESPACE_NAME       BLOCK_ID   BYTES     BLOCKS
--------------------- ---------- ---------- ----------
TEST_EXT2                             4      65536              8   -------(1)

SQL> alter user hoge quota unlimited on TEST_EXT2;

ユーザーが変更されました。

SQL> connect hoge/hoge
接続されました。


SQL> create table test_ext2(co1 number) tablespace TEST_EXT2;

表が作成されました。

SQL> connect /as sysdba
接続されました。


SQL> select owner,tablespace_name,table_name,segment_created from dba_tables where table_name= 'TEST_EXT2';

OWNER      TABLESPACE_NAME TABLE_NAME SEGMENT_CREATED
---------- ---------------     ----------    --------------------
HOGE          TEST_EXT2            TEST_EXT2        NO -------(2)

2話目で書きましたが、遅延セグメント作成な状態で、セグメントは作成されていません。



SQL> select tablespace_name,file_id from dba_data_files where tablespace_name='TEST_EXT2';
TABLESPACE_NAME    FILE_ID
--------------- ----------
TEST_EXT2                  14   -------(3)

(1)よりデータブロックの空きは4ブロック目(含む)から8ブロックなので、
11ブロック目が最期のブロックだと判断します。


ファイル番号14番のデータファイルの1ブロック目から11ブロックまでの
dumpを取得します。

SQL> alter system dump datafile 14 block min 1 block max 11;

システムが変更されました。


diag\<DB_NAME>\<INSTANCE_NAME>\trace配下に出力された
dumpファイルを確認します。


先頭辺り
--------

*** 2012-09-11 11:02:09.047
*** SESSION ID:(9.37) 2012-09-11 11:02:09.047
*** CLIENT ID:() 2012-09-11 11:02:09.047
*** SERVICE NAME:(SYS$USERS) 2012-09-11 11:02:09.047
*** MODULE NAME:(sqlplus.exe) 2012-09-11 11:02:09.047
*** ACTION NAME:() 2012-09-11 11:02:09.047

Start dump data blocks tsn: 12 file#:14 minblk 1 maxblk 11
Block 1 (file header) not dumped:use dump file header command   -------(4)

早々に注意されています。1ブロック目はファイルヘッダーブロックだから、
ファイルヘッダーをダンプするコマンド使いなさいと。

まあ、1ブロック目がファイルヘッダーブロックってことは分かりました。


2ブロック目を確認
rdba(相対データ・ブロック・アドレス)という文字列を検索して2ブロック目を探します。
----------------------------
Block dump from disk:
buffer tsn: 12 rdba: 0x03800002 (14/2)    -------(5)
scn: 0x0000.00398ff6 seq: 0x03 flg: 0x04 tail: 0x8ff61d03
frmt: 0x02 chkval: 0x75b5 type: 0x1d=KTFB Bitmapped File Space Header   -------(6)


(5)がrdbaですね、(file_id/ブロック番号)なので、
14番のデータファイルの2ブロック目ということがわかります。

(6)を見てみると、「Bitmapped File Space Header」とあります。
このブロックが、 ビットマップ・ヘッダ・ブロックと考えてよさそうです。


3ブロック目を確認
----------------------------
Block dump from disk:
buffer tsn: 12 rdba: 0x03800003 (14/3)   -------(7)
scn: 0x0000.0039ecd1 seq: 0x01 flg: 0x04 tail: 0xecd11e01
frmt: 0x02 chkval: 0x43ae type: 0x1e=KTFB Bitmapped File Space Bitmap   -------(8)


(7)より14番のデータファイルの3ブロック目ということがわかります。

(8)を見てみると、「Bitmapped File Space Bitmap」とあります。
このブロックが、 ビットマップ・ブロックと考えてよさそうです。


4ブロック目を確認
----------------------------
Block dump from disk:
buffer tsn: 12 rdba: 0x00000004 (0/4)   -------(9)
scn: 0x0000.00000000 seq: 0x01 flg: 0x05 tail: 0x00000001
frmt: 0x02 chkval: 0xa704 type: 0x00=unknown   -------(10)

14/4が見つかりません。ファイルの終わりまで見ると(9)の部分が、(0/11)まであります。
8ブロック。。(10)はunknownになっています。

遅延セグメント作成でセグメントが作成されていないので、
空き領域になっているんですかね。



一先ず、1~3ブロック目までは、技術文書通りだということが分かって、スッキリ!!


次回は、遅延セグメント作成のセグメントに行を追加して、どうなるかを見てみます。


INITIAL_EXTENTと遅延セグメント作成な話3


前回で終わったーと思って寝たのですが。
前々回の先頭3ブロックが気になる。。

そして、OS上で1ブロック分領域が多く獲得されているのも気になる。。。

ということで続きます。

何度も書いてますが、役に立つ内容ではないですね。

ローカル管理表領域

ローカル管理表領域では、データファイル・ヘッダー内に、データファイル本体の空き領域および使用済領域を追跡するためのビットマップが保持されています。各ビットは、1ブロック・グループに対応します。領域が割り当てられるか、解放されると、Oracle Databaseでは、ビットマップの値がブロックの新しい状態を反映する値に変更されます。




でした。でした。ディクショナリ管理と違って、エクステント内の領域を使用または解放について、
領域を管理するためのデータ・ディクショナリ表の更新をしなくてよくなったんですよね。
ディクショナリ管理時は、ディクショナリの更新のための再帰SQLの発行や競合による待ち、
redoの生成とか色々な課題があったんですよね。


ローカル管理表領域だと、自分の表領域内で領域の使用状況をビットマップで管理することによって、
エクステントの管理にデータ・ディクショナリを使用する必要がなくったので、
上記のような課題を解消してパフォーマンスがアップしたのでした。


ということで、使えない先頭3ブロックにはビットマップ情報の情報がきっと入ってるんだろうなぁ。。。

・・・KROWNの文書番号:29765に中にちゃんと書いてありますね。。



1ブロック目:データファイルヘッダー。デーファイル毎の1ブロック目
        データファイルの管理情報を格納

2ブロック目: ビットマップ・ヘッダ・ブロック。ローカル管理表領域デーファイル毎の
        2ブロック目※。ローカル管理するための管理情報を格納
        ※最初からローカル管理としてデータファイルを作った場合のみ


3ブロック目: ビットマップ・ブロック。ローカル管理表領域デーファイル毎の
        3ブロック目移行に1個以上獲得される。
        実際の領域管理のためのビットマップ情報を格納。


とすると88KBは、(上記3ブロック+セグメント用8ブロック)×8で88KBか。


96KBとOS上で見えている、残り1ブロック分の領域。
これもKROWNの文書番号:29765に書いてありました。

OS側でのファイル管理用領域なんですね。
以下のSQL文で確認ができます。



SQL> select a.FILE_NAME,b.BLOCK1_OFFSET from dba_data_files a,v$datafile b where a.file_id=b.file# and a.tablespace_name='TEST_EXT';


FILE_NAME                                                   BLOCK1_OFFSET
---------------------------------------------      -------------
C:\APP\ORACLE\ORADATA\ORCL\TEST_EXT01.DBF              8192


BLOCK1_OFFSET:ファイルの最初からOracleの共通情報の開始点へのオフセット


確かにデータファイルの8KB以降からOracleの情報が開始されるみたいですね。


ということで、96KBの謎が解けた。

スッキリ!


でも、まだ、ちょっとだけ気になるのでしつこく続けます。


次回:INITIAL_EXTENTと遅延セグメント作成な話4

2012年9月10日月曜日

INITIAL_EXTENTと遅延セグメント作成な話2


前回に引き続き、どうでもいい内容を検証していきます。


表領域にオブジェクトを作っていきます。


SQL> create table test_ext(co1 number) tablespace TEST_EXT;

表が作成されました。


SQL>  select OWNER,SEGMENT_NAME,EXTENT_ID,BLOCKS,BYTES from dba_extents where TABLESPACE_NAME like 'TEST_EXT%';

OWNER  SEGMENT_NAME     EXTENT_ID     BLOCKS      BYTES
------- --------------- ---------- ---------- ----------
SYS        TEST_EXT                   0                  8              65536



SQL>  select TABLESPACE_NAME,BLOCK_ID,BYTES,BLOCKS from dba_free_space where tablespace_name like 'TEST_EXT';

レコードが選択されませんでした。


うんうん。データベース記憶域の割当ての論理単位はエクステント単位だもんね。
MIN_EXTENTSの1エクステント(8ブロック)使っちゃったもんね。うんうん。


うん・・・

ん??


あえ、確か最近のバージョンからは、オブジェクト作成しただけじゃ、
セグメント作成(領域獲得)しなくて、行が挿入されたときに初めて、
セグメント作成されるんじゃなかったっけ、、、

えっとぉ、、、
そうそう、11.2.0.1.0からの新機能「遅延セグメント作成」
※パーティションは11.2.0.2.0からなので、要注意。

詳しくは、Oracle® Database概要 11gリリース2(11.2) 12章 論理記憶域構造 参照


確認してみます。


SQL> show parameter DEFERRED_SEGMENT_CREATION

NAME                                 TYPE        VALUE
----------------------- ----------- ------------------------------
deferred_segment_creation     boolean     TRUE



遅延セグメント圧縮機能は有効になっています。



SQL> select OWNER,TABLE_NAME,SEGMENT_CREATED from dba_tables where table_name='TEST_EXT';

OWNER       TABLE_NAME     SEGMENT_CREATED
--------- --------------- -------------------
SYS           TEST_EXT                      YES



でもセグメント作られてますな。。。


そもそもSYSで作ったのがいけないのかなぁ。。怪しそう。。。


試します。



SQL> create tablespace test_ext2 datafile 'C:\app\oracle\oradata\orcl\test_ext2_01.dbf' size 81K;

表領域が作成されました。



SQL> select TABLESPACE_NAME,BLOCK_ID,BYTES,BLOCKS from dba_free_space where tablespace_name like 'TEST_EXT%';

TABLESPACE_NAME       BLOCK_ID   BYTES     BLOCKS
--------------------- ---------- ---------- ----------
TEST_EXT2                             4      65536              8




SQL> alter user hoge quota unlimited on TEST_EXT2;

ユーザーが変更されました。


SQL> connect hoge/hoge
接続されました。


SQL> create table test_ext2(co1 number) tablespace TEST_EXT2;

表が作成されました。




SQL> select owner,tablespace_name,table_name,segment_created from dba_tables where table_name like 'TEST_EXT%';

OWNER      TABLESPACE_NAME TABLE_NAME SEGMENT_CREATED
---------- ---------------     ----------    --------------------
SYS            TEST_EXT              TEST_EXT         YES
HOGE          TEST_EXT2            TEST_EXT2        NO


お、HOGEのTEST_EXT2はセグメント作成されていない。



SQL>  select OWNER,SEGMENT_NAME,EXTENT_ID,BLOCKS,BYTES from dba_extents where TABLESPACE_NAME like 'TEST_EXT%';

OWNER  SEGMENT_NAME     EXTENT_ID     BLOCKS      BYTES
------- --------------- ---------- ---------- ----------
SYS          TEST_EXT                   0              8        65536


うんうん。HOGEのTEST_EXT2がない。
※dba_extentsはセグメントを含むエクステントの情報だから



SQL> select TABLESPACE_NAME,BLOCK_ID,BYTES,BLOCKS from dba_free_space where tablespace_name like 'TEST_EXT%';

TABLESPACE_NAME   BLOCK_ID      BYTES     BLOCKS
---------------    ---------- ---------- ----------
TEST_EXT2                    4         65536          8




うん。うん。空いてますな。



ということで、SYSのオブジェクトは遅延セグメント作成しないってことだな。


という内容が、KROWNの文書番号:137280が遅延セグメント作成機能についてですが、
やっぱりSYSは対象外と書いてありますね。




SQL> connect hoge/hoge
接続されました。
SQL> insert into test_ext2 values(1);

1行が作成されました。

SQL> commit;

コミットが完了しました。

SQL> connect /as sysdba
接続されました。
SQL> select owner,tablespace_name,table_name,segment_created from dba_tables where table_name like 'TEST_EXT%';

OWNER      TABLESPACE_NAME TABLE_NAME  SEGMENT_CREATED
---------- ---------------   ----------   --------------------
SYS          TEST_EXT            TEST_EXT      YES
HOGE        TEST_EXT2          TEST_EXT2     YES




SQL>  select TABLESPACE_NAME,BLOCK_ID,BYTES,BLOCKS from dba_free_space where tablespace_name like 'TEST_EXT%';

レコードが選択されませんでした。




SQL>   CREATE TABLE TEST_EXT3(col1 number)
  2    STORAGE(INITIAL 100M) TABLESPACE TEST_EXT2;

とかやっても、領域は取得しないし、表領域は拡張しないし、
データファイルも大きくならないので、勘違いは禁物ってことで。


SQL> CREATE TABLE TEST_EXT3(col1 number) SEGMENT CREATION IMMEDIATE
  STORAGE(INITIAL 100M) TABLESPACE TEST_EXT2;



データ挿入時に領域獲得させたくないとかであれば、
「SEGMENT CREATION IMMEDIATE」付けましょう。



ということで、だから何?って感じですが、満足したのでした。


次回:INITIAL_EXTENTと遅延セグメント作成な話3


INITIAL_EXTENTと遅延セグメント作成な話1


ちょっと気になったのでやってみたのだけど、
個人的にはツボったのでメモしておく。
何の得もない内容です。

----
環境
----
Windows7 64bit
Oracle: 11.2.0.3.0 64bit



SQL> select TABLESPACE_NAME,INITIAL_EXTENT,MIN_EXTENTS from dba_tablespaces where tablespace_name like 'TEST_EXT%';

TABLESPACE_NAME                INITIAL_EXTENT MIN_EXTENTS
--------------------------- -------------- -----------
TEST_EXT                                    65536              1

INITIAL_EXTENT :初期エクステントのデフォルトのサイズ
MIN_EXTENTS:エクステントのデフォルトの最小数

それぞれよく見る数値です。

初期エクステントサイズは64KBで、1ブロック8KBとすると、
エクステントは1個で、初期エクステントは8ブロックですね。


じゃ、64KBで表領域作れるってこと?

SQL>create tablespace test_ext datafile 'C:\app\oracle\oradata\orcl\test_ext01.dbf' size 64K;


create tablespace test_ext datafile 'C:\app\oracle\oradata\orcl\test_ext01.dbf' size 64K
*
行1でエラーが発生しました。:
ORA-03214: 指定したファイル・サイズが必要最小値を下回っています。

うーん、エラー
まぁ、管理情報とかのオーバーヘッドもあるよね、
64KBから1KBずつ増やしていきます。


SQL> create tablespace test_ext datafile 'C:\app\oracle\oradata\orcl\test_ext01.dbf' size 81K;

表領域が作成されました。



81KBで作れました。


ちなみに、KROWNでエラー番号を検索すると、文書番号:35170に
表領域の最低値の目安が書いてあります。


使用可能エクステントを確認します。
SQL> select TABLESPACE_NAME,BLOCK_ID,BYTES,BLOCKS from dba_free_space where tablespace_name like 'TEST_EXT%';


TABLESPACE_NAME   BLOCK_ID   BYTES     BLOCKS
------------------- ---------- ---------- ----------
TEST_EXT                       4             65536          8


ブロックID4から8ブロック64KB使えるようです。
ブロックID4より前の3ブロックは管理用に使ってるんですかね。

あり??
8KB×12ブロック=96KB。。。

81KBで作ったのに???


SQL> select tablespace_name,bytes/1024 from dba_data_files where tablespace_name ='TEST_EXT';

TABLESPACE_NAME            BYTES/1024
------------------------ ----------
TEST_EXT                               88


ん?88KB=11ブロック??


C:\app\oracle\oradata\orcl>dir TEST_EXT01.DBF

98,304 TEST_EXT01.DBF

!!

96KB!? 12ブロックだ。。


ぐぬぬぬ。油断ならん。。


次回は、表領域が出来たのでオブジェクトを作っていきます。

次回:INITIAL_EXTENTと遅延セグメント作成な話2