
Transaction - 日本エクセム株式会社 Oracle 技術情報
目次[非表示]
オラクルトランザクション(Transaction)を完全に理解すると言うことは、Oracleを完全に理解しているのと同じ意味を持ちます。トランザクションを理解するには、オラクルが提供する制御機能と内部構造、アルゴリズムの理解が必要となる為です。また、RACのようなマルチノード環境では、複数のノード間のトランザクションの同期まで必要なため、その複雑さは想像を絶することとなります。
ユーザーがDMLを実行すると、(つまり、トランザクションを実行すると、)Oracleは内部的には、次のような手順で作業を進めます。
1)トランザクションに対して、UNDOセグメント(Undo segment)を割り当てます。
この場合、現在のオンライン状態であるのUNDOセグメントのいずれかを優先的に使用します。
UNDOセグメントの選択は、ランダムに行われ、他のトランザクションが使用中であれば、3回まで再試行されます。
このプロセスが失敗した場合、オフライン状態のUNDOセグメントをオンライン化して使用します。
もしこの過程までも失敗した場合は、新しいUNDOセグメントを生成します。
このプロセスを通じて、UNDOセグメントを割り当てられなければ、
Oracle 8iで使っていたロールバックセグメント(Rollback Segment)アルゴリズムを使用します。
つまり、すでに他のトランザクションによって使用されているUNDOセグメントの中で最も使用量が少ないものを使用します。
サーバプロセスが、UNDOセグメントを獲得した時点で適切なオンラインのUNDOセグメントが存在しない場合、
オンライン状態のUNDOセグメントが確保されるまで、enq:US – contentionイベントを待機します。
2)UNDOセグメントが割り当てられれば、UNDOセグメントヘッダーにトランザクションテーブルスロット(transaction table slot)を生成します。
3)トランザクションテーブルを作成した後、TXID(Transaction ID)を生成し、現在のトランザクションに割り当てます。
TXIDはV $ TRANSACTIONビューのXIDUSN、XIDSLOT、XIDSQNで表現されますが、この値は、
トランザクションに割り当てられたUNDO域のUNDOセグメントヘッダに存在する
トランザクションテーブルの正確な位置を指します。トランザクションは、必ず、
UNDO領域を割り当てられた後にIDを付与されることに注意してください。
4)トランザクションの対象となるブロックをバッファ・キャッシュにロードし、
ブロックヘッダのITL(Interested Transaction List)にトランザクションエントリ(Transaction Entry)を登録します。
もしITLにエントリを登録するスペースがない場合は、スペースが確保されるまで、
enq:TX – allocate ITL entryイベントを待機します。
5)変更ブロックの変更情報は、PGAにチェンジベクターという名前で保存されます。
通常、1つの行が変更された場合、それぞれ、UNDOヘッダブロック(チェンジベクトル#1)、
UNDOブロック(チェンジベクトル#2)、データブロック(チェンジベクター#3)に対応するチェンジベクターが生じます。
プロセスは、PGAのチェンジベクターを、REDOレコード(または、REDOエントリ)という名前で、
REDOバッファ(Redo Buffer)にコピーします。REDOバッファに変更をコピーする過程でredo copyラッチ、
redo allocationラッチ、redo writingラッチを獲得しなければなりません。この過程で、ラッチの競合が発生した場合、
それぞれlatch:redo copy、latch:redo allocation、latch:redo writingイベントを待機します。
6)前のイメージ(Before Image)についての情報をUNDOブロックに記録し、データブロックを変更します。
変更されたデータブロックはダーティ(Dirty)状態になります。
また、変更されたデータブロックのCRブロックがバッファキャッシュに生成されます。
もし変更したいローが現在別のトランザクションによって変更中
(つまり変更後まだトランザクションが終了していない状態)であれば、
そのトランザクションが終了するまで待たなければならない場合、
enq:TX – row lock contentionイベントを待機します。
7)コミットが実行されると、トランザクションにSCNを割り当てます。
コミット情報は、REDOバッファに格納されます。
8)UNDOセグメントヘッダのトランザクションテーブルにコミットが行われたことを保存して、
ロックを含むすべてのリソースの占有を解除します。
9)REDOバッファの内容がREDOログ・ファイルに記録されます。
変更されたブロックは、以降DBWRプロセスによってデータファイルに記録されます。