ロックに関する検証 その4

~ロックに関する検証 その4~
ペンネーム ちゃむ

前回は、トランザクションロックに関しての検証を行った。
今回は、インデックスが作成してあるテーブルに対して更新処理を行ったとき
の、トランザクションロックに関しての検証を行う。

実は、テーブルとインデックスを作成するときのinittransのデフォルト値は違
う。

          テーブル インデックス
          --------  ------------
inittrans        1             2

inittransは、トランザクションエントリの初期値を設定するものである。つま
り、事前にこの分だけトランザクションエントリを格納する領域を確保する。

なぜ、インデックスのデフォルト値は2なのであろうか。仕様だからと言ってし
まえばそれまでだが、インデックスを更新する際の動きに起因していると思う。

検証には、以下のテーブル a_2 と、インデックス a_2_idx を使用する。
t10man_orgは、empnoを連番にして、emp表を10万件に拡張したものである。

*************** テーブル a_2 及び インデックス a_2_idx ***************

SQL> create table a_2 as select * from t10man_org where rownum create index a_2_idx on a_2(empno) ;

まずは、TREEDUMPを取得して、テーブルの構造を把握する。
(TREE DUMPの詳細は、インデックスに関する検証を参照)

はじめに、インデックスのオブジェクトIDを検索する。

SQL> select object_id from dba_objects where object_name = 'a_2_idx' ;

OBJECT_ID
---------
     5574

SQL> ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME TREEDUMP LEVEL 5574' ;

その OBJECT_ID を指定して、TREEDUMPを取得する(この情報は、初期化パラメータ
のUSER_DUMP_DESTに出力される)。

-----------------------TREEDUMP-----------------------

branch: 0x100fc36 16841782 (0: nrow: 10, level: 1)     ←ブランチブロック
   leaf: 0x100fc37 16841783 (-1: nrow: 116 rrow: 116)  ←EMPNO 1~116
   leaf: 0x100fc38 16841784 (0: nrow: 110 rrow: 110)   ←EMPNO 117~226
   leaf: 0x100fc39 16841785 (1: nrow: 110 rrow: 110)   ←EMPNO 227~336
   leaf: 0x100fc3a 16841786 (2: nrow: 110 rrow: 110)   ←EMPNO 337~446
   leaf: 0x100fc3b 16841787 (3: nrow: 110 rrow: 110)   ←EMPNO 447~556
   leaf: 0x100fc3c 16841788 (4: nrow: 110 rrow: 110)   ←EMPNO 557~666
   leaf: 0x100fc3d 16841789 (5: nrow: 110 rrow: 110)   ←EMPNO 667~776
   leaf: 0x100fc3e 16841790 (6: nrow: 110 rrow: 110)   ←EMPNO 777~886
   leaf: 0x100fc3f 16841791 (7: nrow: 110 rrow: 110)   ←EMPNO 887~996
   leaf: 0x100fc40 16841792 (8: nrow: 3 rrow: 3)       ←EMPNO 997~999

------------------------------------------------------

これを図で示したものを以下に示す。

この構造を理解した上で、例えば、以下のSQL文を発行したらどうなるであろう

か?

SQL> update a_2 set empno=1000 where empno=1 ;

インデックス上では、EMPNO=1が格納されているブロックと、EMPNO=1000が格納
されているブロックが異なるため、それぞれのブロックでトランザクションエ
ントリが格納される。つまり、一回の更新処理で2つのトランザクションエント
リが格納されるのである。

以下にそのイメージ図を示す。

また、以下に、EMPNO=1 と EMPNO=1000 が格納してあるインデックスのブロッ

クダンプの一部を示す。

***************************** EMPNO=1が格納されているブロック *****************************

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   xid:  0x0000.000.00000000    uba: 0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x02   xid:  0x0007.00a.000000b2    uba: 0x00801e8c.0200.04  ----    1  fsc 0x000e.00000000

row#0[1880] flag: ---D-, lock: 2          ← LOCKのフラグがセット(deleteフラグもセット)
col 0; len 2; (2):  c1 02                 ← EMPNO=1
col 1; len 6; (6):  01 00 e1 e4 00 00
row#1[1868] flag: -----, lock: 0
col 0; len 2; (2):  c1 03                 ← EMPNO=2
col 1; len 6; (6):  01 00 e1 e4 00 01

*******************************************************************************************

*************************** EMPNO=1000が格納されているブロック ****************************

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   xid:  0x0000.000.00000000    uba: 0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x02   xid:  0x0007.00a.000000b2    uba: 0x00801e8c.0200.05  ----    1  fsc 0x0000.00000000

col 1; len 6; (6):  01 00 fc 2b 00 0b
row#2[1853] flag: -----, lock: 0
col 0; len 3; (3):  c2 0a 64              ← EMPNO=999
col 1; len 6; (6):  01 00 fc 2b 00 0c
row#3[1841] flag: -----, lock: 2          ← LOCKのフラグがセット
col 0; len 2; (2):  c2 0b                 ← EMPNO=1000
col 1; len 6; (6):  01 00 e1 e4 00 00

*******************************************************************************************

インデックスのinittransのデフォルト値が2なのは、このように、update文を
発行したときに、複数のトランザクションエントリが必要になる可能性が高い
のも理由の一つと考えられないであろうか。

以上 茅ヶ崎にて