遅延ブロッククリーンアウト

遅延ブロッククリーンアウトとは、データブロックのステータスの更新を UNDO の領域(トランザクション表)を利用することで実質的に先延ばしする。 これによって大量に削除・更新を行なっているトランザクションを見かけ上、高速に完了することができる。

先延ばしされた処理は次回ブロックが参照されたときに実行される。

なぜデータブロックの管理領域を直ぐに更新しないか?

バッファ上にそのブロックが存在した状態で COMMIT すれば速やかに更新される。しかしバッファは大きなトランザクションに比べると小さいのが普通である。

そしてバッファの内容は COMMIT する前に追い出されて データベースライタ (DBWn) によってデータファイルに書き出される。つまり、ステータスはコミットされていない状態。

ステータスの更新のためにブロックを再読み込みしていたら I/O 処理が2倍になる恐れがある。
これを効率よく回避するためにブロックのステータス更新を必要になるときまで先送りして、別途保管しておいてしまえのが遅延ブロッククリーンアウトという仕組み。

その場所として COMMIT したときには UNDO セグメントを解放するために読み書きする必要がある。このヘッダ領域を一時保管領域に都合よく使ってしまおう、という発想である(たぶん)。

後々、ステータスの更新が済んでいないデータブロックが読み込まれる機会が発生すると ITL を経由して UNDO のヘッダのトランザクション表(トランザクションスロット)が参照される。
このとき、そのブロックが過去に COMMIT 済だったことが判明し、ついでにデータブロックのステータスを更新しましょうというわけである。

これは一種のツケであり、ツケがたくさんある状態を放っておくとテーブルフルスキャンが発生したときに、すべて一括で清算しなくてはならない。
すなわち COMMIT 間隔の長い大量更新を行なうと更新バッチ処理のパフォーマンス良いが、次にフェッチする処理(※1) に速度面で影響が発生する。

(※1) そのブロックにアクセスする、すべての SQL が対象になる。(SELECT 文も含む)
テーブルのブロックだけではなくインデックスも遅延ブロック・クリーンアウトの対象になっていることを忘れてはいけない。

大量削除や更新した直後の SELECT COUNT(*) FROM 〜 は、2回目の SELECT COUNT(*) に比べて非常に遅い。これは2回目においてキャッシュが効いて速いというよりも、最初の SELECT においてブロックのクリーンアウト処理が発生してデータブロックの書き込み処理によって遅くなっているためである。
このツケチェックポイント やシャットダウン時にも解消されない。(※2)
ノーアーカイブログモードで shutdown abort 終了の場合、オンラインだった UNDO を消失すると REDO ログがあってもデータを復旧できなくなる可能性がある。
ちなみに自動管理の UNDO 表領域を縮退させるために付け替える?とき、PENDING OFFLINE でない場合でも、直ぐに DROP できないことがある。このとき UNDO に残された情報のクリーンアウト用のトランザクション表の移行を行なっているのかもしれない。

(※2) UNDO 領域は COMMIT、または、ROLLBACK された後に 期限切れ(※3) になると再利用可能になる。状況によっては別の領域(遅延ロールバックセグメント)に退避される。

(※3) 期限切れの制御は UNDO_RETENTION 初期化パラメータと UNDO 表領域の GURANTEE 属性 Oracle 10g によって変わる。



遅延ブロック・クリーンアウトの例え話

身近な例に置き換えるなら

ある仕事場の風景

  • は非常に忙しい人で売れっ子だ、いろんな会社から仕事が殺到する、無駄な作業はできない。
  • そこへZ社Bさんが、色んな会社を引き連れてプロジェクトXを持ってきた。
    なんて多い仕事量だ、即座にその仕事をこなして渡せる量ではない。
  • 全員が、自社の分だけ終わると全体の整合性を確認しないでタクシー会社に戻ってしまう。Bさんにいたっては、まだ完成していない資料をコピーして持っていくありさまだ。
  • AはやっとBさんからの依頼の仕事を完全に終えた。
  • プロジェクトXは、整合性も問題なく完璧だ、不整合なら即座に関係各社を召集するところであった。
  • Aは、おもむろに判子をついて、脇の完了済のボックスにおく、帰ってしまうBさんへなどに届けに行かない。
  • Aは、今日も終電が近づいたので仕方なく、仕事を切り上げて帰り、ぐっすり眠った。

翌朝…

  • Aは今日も忙しい、始発から会社にきていた。Bさんへ完了した旨の書類を渡しにいくなど考えもしていない。
  • そこへCさん(Bさんと同じ会社)が、別件の仕事を持ってきた。これはその場で終了させて渡すことができた。
  • AはプロジェクトXを思い出してCさんにお願い事をする。
    完了済のボックスからX社のポストイットを頼りに書類を引っ張り出す。
    これ、Bさんからの仕事の書類です、Bさんに終ったことを伝えてくたさいと言って書類を渡した。
  • 他の社も催促か別件で自分のところへやってくるはずだ、Aは、そう確信して今日も働く。
  • こりゃー、今日も終電か…と、ひとり小さな声で呟くAなのであった。-- おわり

三文芝居の登場人物とイベント

主人公 A
オラクルのサーバープロセス(主役:モットー、徹夜はしない)
プロジェクトX
トランザクション
(プロジェクトXはジョイント・ベンチャーなのでたくさんの会社で行なわれている)
Z社(会社)
ある データブロックZ(住所が 16進数で書かれている洒落た会社だ)
Bさん
自分を変えたい UPDATE
Cさん
いつも、自分探しをしている SELECT
他にも INSERT 、UPDATE と DELETE などの同僚がいる。
タクシー
DBWn データベースライタプロセス
景気が良いと数台走っているが相乗りしないと燃費が悪いので、お客が集まるまで出発を拒否されることがある。
会社に戻ってしまう
トランザクションの終了を待たずにデータファイルに書き出される。
判子をつく
COMMIT フラグを立てる。
ポストイット
データブロックの ITL:Interested Transaction List
使いすぎや経費削減によって良く足りなくなる。そのときにAの機嫌がわるいと ORA-01555 〜 と叫んで仕事をやめてしまうことがある。
関係各社を召集
ロールバック発生、UNDO からデータを復活させる。
完了済のボックス
UNDO セグメント・ヘッダ(トランザクション表)
この箱をなくすと、どれが COMMIT 済だったか分からなくなる。トランザクションスロットの上書きによって ORA-01555 の原因にもなる。
終電
データベースのシャットダウン(正常終了)
重要 シャットダウンを行なっても UNDO セグメント(完了済のボックス)には重要な情報が保持されている。
始発
データベースのスタートアップ


関連事項

日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ Oracle のライセンスがわからない…
Oracle Direct (ネットで聞いても最後はここで要確認)