トランザクションエントリに関する検証 その1

<トランザクションエントリに関する検証 その1>
ペンネーム しゅらん

今週からはテーブルやインデックスを作成する際に設定するinitrans、
maxtransについて検証をしてみたいと思います。

—initransとmaxtrans—

テーブルやインデックスの設計をしていると、I/Oの分散のためにデータファ
イルの配置に苦心したり、EXTENTのサイズなどを綿密に計算して設定を行った
りしますがinitrans、maxtransについては、あまり意識して変更する必要がな
いパラメータだと思われている方も多いのではないでしょうか。
今回はそのinitrans、maxtransについて検証を交えながら解説を行っていきま
す。

—initrans、maxtransとはなにか?—

テーブルやインデックスのデータを更新する際(INSERT文やUPDATE文、DELETE
文など)には、実際に更新されるブロックの内部にトランザクション(ITL)
エントリという、ブロックを更新するトランザクションの情報を保持する領
域が一時的に確保されます。トランザクションエントリのサイズは23バイトで、
複数のトランザクションが同時に同一ブロックに対して書込みを行う際には
そのトランザクションの数だけ確保されます。

この領域を確保するための空きをinitransで設定された数だけ、あらかじめブ
ロック内に確保しておきます。このinitransで確保された空きが使い果たされ
ると、最大でmaxtransで設定された値、またはブロック内の使用可能領域が無
くなるまで動的に確保することができます。

CREATE TABLE時のDEFAULTはinitrans 1 maxtrans 255 となっており、明示的
にもmaxtransは255まで設定出来ますが、実際にはブロックサイズによって決
定されます。

    ブロックサイズ  トランザクションエントリの最大値 
         2K                        41
         4K                        84
         8K                       169
        16K                       255

—maxtransに関する検証 ブロック格納率—

では実際にmaxtransと同数以上の同時アクセスを発生させると、どうなるの
でしょうか。

23バイト*169(検証環境はブロックサイズ8K)=3887バイトのトランザクション
エントリが確保され、8Kのブロックサイズの約半分弱はトランザクション用の
一時的な領域として使用され、その領域は無駄な領域になってしまうのでしょ
うか?

今回はブロック使用率を分かりやすくさせるために、INSERTのみが発行される
トランザクションを発生させる。おなじみの弊社自社開発インタプリタ言語
「POPSQL」を使用して、専用接続を200まで増やして同時INSERTを行う。

このテストプログラムでは200のSESSIONが1行INSERT&COMMITを
1000回繰り返し行う。

検証環境
OS:AIX5L
Oracle:8.1.7

maxtrans255(今回はブロックッサイズ8Kのため、実際には169)でテスト用の
テーブルを作成

CREATE TABLE TBL_SHU1 (ID   DATE DEFAULT SYSDATE,
                       TEXT CHAR(10))
                       INITRANS 1 MAXTRANS 255 PCTFREE 10
                       STORAGE ( INITIAL     20M
                                 NEXT        20M
                                 PCTINCREASE  0
                                 MAXEXTENTS  UNLIMITED);

—200 session—

上記テストプログラム実行後、ANALYZEを行いブロックの使用状況を確認

analyze table tbl_shu1 compute statistics;

select TABLE_NAME,NUM_ROWS,BLOCKS from dba_tables 
where table_name='TBL_SHU1';

TABLE_NAME                       NUM_ROWS     BLOCKS
------------------------------ ---------- ----------
TBL_SHU1                           200000        850

850block ということは、850*8K=約6.64MBを使用している。

—1 session—
次に上記のテーブルをtruncate後、session数を1に変更して、20万件insertを
実行してみる。

上記テストプログラム実行後、ANALYZEを行いブロックの使用状況を確認

analyze table tbl_shu1 compute statistics;

select TABLE_NAME,NUM_ROWS,BLOCKS from dba_tables 
where table_name='TBL_SHU1';

TABLE_NAME                       NUM_ROWS     BLOCKS
------------------------------ ---------- ----------
TBL_SHU1                           200000        665

665block ということは、665*8K=約5.19MBを使用している。

200sessisonと比べると、約78%となっている。半分にまではならなかったが、
今回の検証環境は、メモリがきつめの環境だったため、同時実行性については
やや疑問が残る、そのためこのくらいの結果となったのだろうか?

次回も引き続きトランザクションエントリについての検証を行います。

以上、突風の吹き荒れる茅ヶ崎にて