ロールバック・セグメントに関する検証 その8
~ロールバック・セグメントに関する検証 その8~
ペンネーム ちゃむ
前回は、読み取り一貫性に関して説明した。
今回は、この読み取り一貫性の仕組みを説明する上では欠かすことのできない
「ORA-1555」のエラーに関して、実際に検証を交えながら説明していく。
ORA-1555は、「スナップショットが古すぎます。」というメッセージであるが、
いったいどのようなものなのであろうか?
ロールバック・セグメントは、以下の図のように、トランザクションに循環的
に使われる。
この更新前の情報は、トランザクションがコミットされた後も別のトランザク
ションにより上書きされるまでは残っている。トランザクションがコミットさ
れるより前に、別のセッションからSELECT文が発行されていると、そのSELECT
文のSCNの方が古いので、更新前情報を必要とする。その後で、そのトランザク
ションがコミットされ、さらに、既に別のトランザクションに上書きされてし
まうと更新前情報を読み込むことができないので、ORA-1555が発生するのである。
ORA-1555が発生するパターンは、次の3つが考えられる。
1.TRN TBLのスロットが上書きされてしまったとき
2.UNDOブロックが上書きされてしまったとき
3.データブロックのITLが上書きされてしまったとき
今回は、そのうちの1.を発生させて検証してみる。
1.を起こすためには、21個のスロットをすべて上書きすればいいのではなか
ろうか?
ということで、22個のトランザクションを一つのロールバック・セグメントに
書き込んでみよう。
ORA-1555を発生させるためには、別セッションでこのSELECT文を実行しておく
必要があるが、小さいテーブルでは、すぐにそのSELECT文の処理が終わってし
まうので、このままではORA-1555は発生しずらい(逆に言うと、大きな表が大
量に更新されるときに、その大きな表が別のセッションからSELECTされるよう
な環境であれば、ORA-1555は発生しやすいといえる)。
ORA-1555を発生させるには、SELECT文が古いSCNを取得する必要があるので、そ
のためにトランザクションレベルの読み取り一貫性を設定する。
SQL> SET TRANSACTION READ ONLY ;
トランザクションが設定されました。
通常の読み取り一貫性とは、文レベルの読み取り一貫性を指す。この文レベル
とは、文が実行される毎に、つまりSELECT文が発行される毎に、現在のSCNを取
得するという意味になる。これが、トランザクションレベルとなると、
SET TRANSACTION READ ONLY ;を発行した後に、実行されるSELECT文をいくつ流
しても、SET TRANSACTION READ ONLY ;を発行した時点のSCNを使用することに
なる(コミットやロールバックを発行してトランザクションが終了するまで)。
これは、アプリケーションである時点において、バッチ的に複数のテーブルを
ジョインしてデータを取得するときなどに使用されるが、今回は、ORA-1555を
起こしやすくするために使用する。
今回は、結果だけを述べよう。実は22個のトランザクションを発生させて、
22個目のトランザクションがスロットを上書きしたにも関わらず、ORA-1555は
発生しなかった。
これは、以下のようにロールバック・セグメントのセグメント・ヘッダーの中
に、トランザクション表の他にTRN CTLという領域が存在する。この領域は、ト
ランザクションテーブル自身のロールバック情報の場所を示すデータを持って
いる。
TRN CTL:: seq: 0x010c chd: 0x000a ctl: 0x0002 inc: 0x00000000 nfb: 0x0000 mgc: 0x8002 xts: 0x0068 flg: 0x0001 opt: 2147483646 (0x7ffffffe) uba: 0x008001e0.010c.06 scn: 0x0000.00ed6ae1
おそらく、この情報が原因で22個目のトランザクションが、トランザクション
テーブルを上書きしても、そのトランザクションテーブル自身のロールバック
情報が存在するため、ORA-1555が発生せずに、検索できてしまったのであろう。
22個のトランザクションでは、「1.TRN TBLのスロットが上書きされてしまっ
たとき」の原因によるORA-1555を発生させるのには不十分であると判断し、次
回は49個のトランザクションを発生させる検証を試みる予定である。
以上 ♪オライチゴーゴーゴー♪ 茅ヶ崎にて