ロールバック・セグメントに関する検証 その9

~ロールバック・セグメントに関する検証 その9~
ペンネーム ちゃむ

今回も、読み取り一貫性の仕組みを説明する上で必ず出てくる「ORA-1555」の
エラーに関して、引き続き検証していく。
前回は、残念ながら22個のトランザクションでは、ORA-1555を発生させるのに
は不十分であると判断して、今回は、49個のトランザクションを発生させる検
証を試みてみることにしよう。

-------------ORA-1555が発生する原因------------------
1.TRN TBLのスロットが上書きされてしまったとき
2.UNDOブロックが上書きされてしまったとき
3.データブロックのITLが上書きされてしまったとき
-----------------------------------------------------

弊社のPOPSQLという言語を用いて、49個のテーブルを、一つのロールバック・
セグメントで、49個のセッションからUPDATEするという簡単な検証プログラム
を作成した。
以下のtrun49_3.callがtrun49_3.jobを49回呼び出す。49個のテーブルは、Emp
表のコピーなのですべてのデータは1ブロックに納まっていて、更新するとUNDO
ブロックも1ブロックに納まる。

使用するロールバック・セグメントはRB_FIND50で、すべてのトランザクション
はこのRB_FIND50に書き込む。
initial 25ブロック、next 25ブロックで作成したので、使用できるブロック数
は、拡張しなければセグメント・ヘッダーを除いた49ブロックである。

SQL> select block_id,blocks from dba_extents where segment_name = 'RB_FIND50' ;

 BLOCK_ID    BLOCKS
--------- ---------
    29439        25
    29464        25

実質的には、block_id = 29440から29488の49ブロックが使用される。
(29439はセグメントヘッダー)

今回の検証は、49個の小さなテーブル(1ブロック)を別セッションでupdateする。
これは、ロールバック・セグメントは、別々のトランザクションの場合、別の
UNDOブロックに順番に書き込まれるという特性を利用した検証である。

************trun49_3.call*************************

CONNECT SCOTT/TIGER

LOOP( I=0 ; I set transaction read only ;

トランザクションが設定されました。

わかりやすくするため、上記のリスト(MESSAGEコマンドの出力結果)は、21行
毎に手で改行を施してある。単純にこのリストだけ見ても、スロットが順番に
使用される様子や、UNDOブロックが順番どおりに使用される様子が見れて面白
い(SLEEP秒数を工夫しないと、このようにきれいな順番では使用されなかった)。

22行目から、スロットを上書きする様子が伺えると思うが、そこでは ORA-1555
が発生しなかった。このように、49個発生させて、やっとポロポロと ORA-1555
が発生したのである。

では、実際の結果はどうであろうか?
結果は、49個のトランザクションを発生させたときには、以下の5つのテーブル
でORA-1555が発生した(事前にSQL> set transaction read only ;を設定した
セッションで発行したSQL文である)。

SQL> select count(*) from a_0
にエラーが発生しました。ORA-01555: スナップショットが古すぎます
(ロールバック・セグメント番号: 17、名前:RB_FIND50が小さすぎます)。

SQL> select count(*) from a_1
にエラーが発生しました。ORA-01555: スナップショットが古すぎます
(ロールバック・セグメント番号: 17、名前:RB_FIND50が小さすぎます)。

SQL> select count(*) from a_2にエラーが発生しました。
ORA-01555: スナップショットが古すぎます
(ロールバック・セグメント番号: 17、名前:RB_FIND50が小さすぎます)。

SQL> select count(*) from a_3
にエラーが発生しました。ORA-01555: スナップショットが古すぎます
(ロールバック・セグメント番号: 17、名前:RB_FIND50が小さすぎます)。

SQL> select count(*) from a_4にエラーが発生しました。
ORA-01555: スナップショットが古すぎます
(ロールバック・セグメント番号: 17、名前:RB_FIND50が小さすぎます)。

まず、ORA-1555が発生した理由についてだが、前述した3つの理由のうちの
「2.UNDOブロックが上書きされてしまったとき」ではない。
ロールバック・セグメントは、49個の使用可能領域があり(initial = 25、
next = 25 の場合)、きれいにその49個のブロックを使用しているので、上書
きされていない様子は分かる。
また、「3.データブロックのITL(テーブルなどのデータブロックにあるトラ
ンザクション情報)が上書きされてしまったとき」でもない。なぜなら、テー
ブルはすべて別々の A_0 から A_48 のテーブルを使用しているからである。

となると、残りは「1.TRN TBLのスロットが上書きされてしまったとき」
しかない。

ただし、21 × 2 = 42 までは、前回説明した「トランザクション表自体のロー
ルバック情報」が存在しているため、ORA-1555は発生しなくても納得がいくが、
それ以降の7つに関しては、ORA-1555がすべて発生しないと納得がいかない。だ
が、結果は 7つのうち 5つしか発生しなかった。

残念ながら、今回はなぜ、7つのテーブルすべてでORA-1555が発生しなかったか
の原因を突き止めることができなかったが、この件に関しては、何時か必ずリ
ベンジしたいと思っている。
読者の方で、何かこれはと思うことがあれば、ご一報いただけるとうれしいっす。

以上 検証敗北 茅ヶ崎にて

今回で、ロールバック・セグメントに関する検証は終わりにしますが、検証が
完結に至れなかったことについてのお詫びとして、読者の皆様限定に、

「♪♪♪ ロールバック・セグメントの歌 ♪♪♪」をささげます。

一度聴いたら、必ず脳裏にやきつくこと請け合いです。
また、複雑なロールバック・セグメントの構造も、この歌を聴けば簡単に理解
できるかもしれません。
仕事中に、この歌を口ずさんでいただけると、我々としては嬉しいです。