REDOとUNDO [アーキテクチャ]

最近読んでいる書籍(下記の参考文献9章 REDOとUNDO)に、Oracleデータベースの最も重要なREDOとUNDOについて詳しく記載されていたので、備忘まで要点をメモしておく。原文の英語を読みやすさを優先して意図を汲んで要約しているので、原文の正確性は損なわれているかもしれないが、そのあたりはご容赦頂きたい。

---
REDOとはトランザクションを記録したログであり、不慮の障害の場合にトランザクションを再生するためのものである。UNDOはその逆に、トランザクションをロールバックするためのものである。REDOはオンラインREDOログファイル(アーカイブログファイル)、UNDOはUNDO表領域(内のセグメント)に記録される。

REDOとUNDOはどのように動作するのか

以下のようなテーブルと索引があるとする。

create table t(x int, y int);
create index ti on t(x);

ここで、以下のトランザクションを例に考えてみる。

(1) insert into t (x,y) values (1,1);
(2) update t set x= x+1 where x=1;
(3) delete from t where x=2;

まず(1)のINSERTのケースを考えてみる。INSERT INTO TはREDOとUNDOを生成する。このとき、バッファキャッシュ上には、テーブル、索引、UNDOセグメントのブロックがディスクから読み込まれ更新される。そして、それらブロックへの更新情報はログとしてREDOログバッファに記録される。

さて、COMMIT前にDBに何らかの障害が発生しサーバがダウンしたとしよう。このとき、なんら問題はない。SGA上のREDOログバッファ、バッファキャッシュ上のダーティブロックはディスクに記録されず、DBサーバ復旧時は、あたかもトランザクションが実行される前の状態のままとなる。

次に、バッファキャッシュが一杯になったケースを考えよう。このとき、バッファキャッシュの空きを作るため、DBWnはダーティブロックをディスクに書き込む必要があるが、その前にLGWRはREDOログバッファをこれらのブロックに関連するトランザクションログをフラッシュさせる。これにより、UNDOのログがディスクに記録されるため、DB障害時に未コミットトランザクションによる変更ブロックをロールバックすることが可能となる。なお、REDOログバッファは、(1)3秒毎、(2)ログバッファの1/3に達したとき、または1MB以上に達したとき、(3)COMMITまたはROLLBACKが発行されたとき、にフラッシュされるため、通常ほとんどのREDOログバッファはフラッシュされた状態になっているはずである。つまり、未コミットの変更ブロックがバッファキャッシュ上にあり、その未コミットの変更のREDOがディスク上にある状態というのは、通常よく発生するありふれた状態なのである。

次に(2)のUPDATEのケース。UPDATEはINSERTと同様の動きをする。ただし、UNDO量はUPDATE前のイメージを保持するため大きくなる。テーブル、索引、UNDOセグメントブロックがバッファキャッシュ上にあり、ログバッファにUPDATEの更新ログが記録された状態(INSERTの更新ログはREDOログファイルに記録)である。

もしこの状態でDBがクラッシュしたらどうなるか。DBのインスタンス起動時にOracleはREDOログファイルを読み込み、このトランザクションログを見つけ、INSERTにより生成された更新ログ(UNDOブロックを含む)からロールフォワードする。UPDATEのREDOログはバッファ上にのみ存在していたので失われるが、COMMITしていないので問題ない。Oracleはクラッシュリカバリの過程でINSERTがCOMMITされていないことを検出し、(記録されたREDOログにより生成された)バッファキャッシュ上のUNDOセグメントの情報(テーブルと索引の更新前情報)からROLLBACKする。これにより、すべては元の状態となる。ディスク上のブロックはINSERTの更新が反映されているかもしれないが、更新が取り消されたバッファキャッシュがやがてフラッシュされるタイミングで反映されるので問題ない。このようにクラッシュリカバリでは2つのフェーズで行われる。始めにロールフォワードにより障害直前の状態に復旧し、その後に未COMMITトランザクションすべてをロールバックする。これによりデータファイルが整合性が取れた状態となる訳である。

ではクラッシュではなく、トランザクションをロールバックしたらどうなるか。OracleはこのトランザクションのUNDOをバッファキャッシュ上またはディスク上のUNDOセグメントを見つけ、バッファキャッシュ上の表のデータと索引にUNDO情報を適用する。もしバッファキャッシュになければディスクから読み込みUNDOを適用する。これらのブロックは後にフラッシュされディスクに反映される。ここで1点明確にしておくと、ロールバックするプロセスにおいて、REDOログは一切関与しないということである。REDOログが使われるのはリカバリとアーカイブのためだけである。ARCnがオンラインREDOログファイルを読み、LGWRが別のREDOログファイルに書き込みを行うだけに十分なデバイスがある限り、ログファイルの競合は発生しない。このようにREDOとUNDOが別となっていないデータベースでは、ログファイルをトランザクションログとして扱っており、ロールバック時にログを読み込むと同時に、ログライターが同じログに書き込みを行うため競合が発生してしまう。OracleはREDOログをシーケンシャルに書き込む。そして、書き込み中には他から読み込みが発生することはない、というアーキテクチャとなっている。

(3)のDELETEのケースでは、DELETEの結果UNDOが生成され、ブロックが更新され、REDOがログバッファに書き込まれる。UPDATEの動きと同じである。

COMMITを行うとどうなるか。OracleはREDOログバッファをディスクへフラッシュする。変更されたブロックはバッファキャッシュ上にあるが、一部はディスクにフラッシュされた状態かもしれない。しかし、重要なのは、このトランザクションを再実行するためのREDOログはディスクに書き込まれており、永続的な状態になっていることである。データファイルの個々のブロックはまだトランザクション実行前の状態かもしれないが、問題はない。障害時にはREDOログファイルにより最新のブロックの状態にすることができるからである。UNDO情報はUNDOセグメントが上書きされ再利用されるまで保持され、読み取り一貫性のために利用される。

COMMITは何をするのか?

COMMITは通常トランザクションの更新量に依存せず非常に高速に完了する。COMMITの処理時間はトランザクションのサイズにかかわらずフラットなのである。これはCOMMITの処理が本質的に少ないからである。なぜなら、COMMITに必要な以下のような処理はほとんど完了している。
・SGA上にUNDOブロックの生成
・SGA上に更新データブロックの生成
・上記2つのREDOをSGA上に生成
・上記3つのサイズと処理時間に応じてデータがディスクへフラッシュされる
・すべてのロックが獲得される

その上で、COMMITすると、残作業として以下が行われる

・このトランザクションのSCNが生成される
・LGWRがログバッファ上の(残りの)ログエントリをディスクに書き込む
・V$LOCK上のロックレコードをリリースする
・バッファキャッシュ上のダーティブロックに対してブロッククリーンアウト(ブロックヘッダ上のロック関連情報の削除)を行う

上記を見ればわかるように、COMMITの処理はほとんどすることがない。一番長い処理はI/O処理を含む、LGWRにより行われる処理である。しかしそれにしても、REDOログバッファの内容は繰り返しフラッシュされているので、その量はかなり削減されているはずである。LGWRはバックグラウンドでREDOログバッファの内容を継続的にフラッシュしていく。これによりCOMMITが長い時間待たせることを防いでいる訳である。

ROLLBACKは何をするのか?

ROLLBACKの時間は更新量に依存する。なぜならROLLBACKは実行した処理を取り消さなければならないからだ。COMMITと同様、一連の処理が実行されなければならないが、ROLLBACKが行われる前に、データベースは既に多くの処理を行っている

・UNDOセグメントのレコードをSGA上に生成する
・更新されたデータブロックをSGA上に生成する
・上記2つのREDOログをSGA上に生成する
・上記3つのサイズと処理時間に応じてデータがディスクへフラッシュされる
・すべてのロックが獲得される

ROLLBACKを行うと、以下が実行される

・すべての更新を取り消す。これはUNDOセグメントからデータブロックを読み込み実行した処理を巻き戻し、UNDOエントリを適用済みとマークする。INSERTなら削除、UPDATEならその変更を元に戻す、DELETEなら再度INSERTする
・すべてのロックをリリースする
---

なお、実際は図やサンプルスクリプトでより具体的に説明されているので、理解を深めたい方は一読をお勧めする。このレベルまで詳しく記載された書籍は日本語ではなかなかないので、この章意外についても時間があれば紹介したいと思う。

◆参考文献

Expert Oracle Database Architecture

Expert Oracle Database Architecture

  • 作者: Thomas Kyte
  • 出版社/メーカー: Apress
  • 発売日: 2014/11/14
  • メディア: ペーパーバック


nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。