続 X$BH に関する検証 その10
<続 X$BH に関する検証 ~その10~>
ペンネーム ちょびひげ
今回も前回に引き続きRACの環境で、データベース・バッファ上のオブジェク
トの状態(ステータス)の変化を見ていきたい。
前回の検証では、以下の競合を見た。
◇Read/Read の競合
◇Read/Write の競合
◇Write/Readの競合
Read(NODE1で読込)/Write(NODE2で書込み)の競合ではNODE1 の共有モードの
カレント・ブロック(SCUR)が読取一貫性のブロック(CR)にコンバート(
ロックダウン)される状態をみた。今回はWrite/Writeの競合で発生するロッ
クダウン時の状態(ステータス)の変化を見ていく。
今回のポイントは、RACチューニングで重要となる以下2つの内容である。
1. Write/Writeの競合で発生するロックダウンは特に負荷の高い処理である。 つまり、これを減らす事がRACチューニングでの1つのポイントとなる。 2. Write/Writeの競合ではロックダウンに伴なって、PI(Past Image)が作 成される。このブロックをデータベース・バッファ上にあまり残さない事 が重要となる。 ※PIに関しては非常に分かりづらい内容なので、検証の中で詳しく説明し ていきたい
以下、負荷の高いロックダウン発生の原因、また、ロックダウンに伴うPIブ
ロック作成などのオーバヘッドになる動きに関して、検証を通して見ていき
たい。
今回の検証環境も以下の通りである。
*************************************************************
□環境(2ノードのRAC構成)
Linux 2.4.9-e.9.30ml
Oracle9i Release 9.2.0.3.0
□テーブル構成
SQL> desc TEST Name Type --------- ------------------ ID1 NUMBER ID2 NUMBER TEXT VARCHAR2(2000)
□ID1にINDEX(TEST_IDX)を付与
□入っているデータは以下の3件
ID1 ID2 TEXT ---------- ---------- -------------------- 1 1 insight 2 2 insight 3 3 insight
まずは、NODE1からUPDATE(Write)を実行する。
**********************************[Write/Writeの競合その1]***
□NODE1でUPDATE(Write)を実行
SQL> update test set text='aaaaa' where id1=2;
<<NODE1の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL TCH ------------- --------------- ---------- -------- ---------- ---------- TEST scur 257 5E5B6000 0 1 TEST xcur 258 5E5AC000 0 1 TEST_IDX scur 1170 5E5AE000 0 1
ここまでは前回のWrite/ReadのUPDATE(Write)と同様の結果である。
では、次にNODE2でもUPDATE(Write)を行ってみる。
**********************************[Write/Writeの競合その2]***
□NODE2でUPDATE(Write)を実行
SQL> update test set text='bbbbb' where id1=3;
<<NODE1の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL TCH ------------- --------------- ---------- -------- ---------- ---------- TEST scur 257 5E5B6000 0 1 TEST pi 258 5E5AC000 1 1 TEST_IDX scur 1170 5E5AE000 0 1
<<NODE2の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL TCH ------------- --------------- ---------- -------- ---------- ---------- TEST scur 257 5E5B4000 0 1 TEST xcur 258 5E5AC000 0 1 TEST_IDX scur 1170 5E5AE000 0 1
冒頭でも述べたようにPIはWrite/Writeの競合時のみに発生する。
NODE1の状況に注目して頂きたい!Past Image(PI)が作成されている。この
ブロックはWrite/Writeの競合が発生した場合に、他NODEに排他のカレント・
ブロックの権限を移譲する必要がある。そのために、カレント・ブロックを
ロックダウンしてCRブロックにする。これが第2のロックダウンである。
ここでいう第2というのは、前回はRead/Write の競合では共有のカレント・
ブロック(scur)からCRブロックへのロックダウンであったが、今回は、排
他のカレントブロック(xcur)からのロックダウンであることを示している。
ここで重要になってくるのは排他のカレント・ブロックからのロックダウン
では、カレントブロックコピー、つまり最新のブロック情報を持つPast Image
(PI)が作成される点である。万一、カレント・ブロックの権限を移譲した
先のNODE(ここではNODE2)でトラブルが発生した場合でも、自NODEのPIに対
してトラブルが発生したノードのREDOログを適用することにより、迅速なリ
カバリが可能な為である。
もし、自NODEにPast Image(PI)がない場合はどうなるであろうか?当然、
最後にディスクに書き込まれたデータに対してREDOログを適用することにな
る。つまり、自ノードで更新した内容がディスクに書き込まれていない場合
は、自NODEと他ノードの2つのREDOログを適用する必要が出てくる。このよう
に、主にリカバリの時間を高速化するための役割をPast Image(PI)が果た
しているわけである。
もう少し、先程の検証結果を見てみよう。最初のロックダウンでPast Image
(PI)のX_TO_NULLが1にカウントアップされている。
NODE2では、共有のカレント・ブロックであるインデックス(TEST_IDX)から
、更新対象のROWIDを特定して、該当ブロックをNODE1からインターコネクト
経由で取得する。最後に、カレント・ブロックに対して更新を行ってUPDATE
が完了でする。
では、再度NODE1でUPDATE(Write)を行ってみよう。
**********************************[Write/Writeの競合その3]***
□NODE1でUPDATE(Write)を実行
SQL> update test set text='ccccc' where id1=2;
<<NODE1の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL TCH ------------- --------------- ---------- -------- ---------- ---------- TEST scur 257 5E5B6000 0 1 TEST xcur 258 5E5A6000 1 1 TEST pi 258 5E5AC000 1 1 TEST_IDX scur 1170 5E5AE000 0 2
<<NODE2の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL TCH ------------- --------------- ---------- -------- ---------- ---------- TEST scur 257 5E5B4000 0 1 TEST pi 258 5E5AC000 1 1 TEST_IDX scur 1170 5E5AE000 0 1
まず、NODE2の状況であるが、1つ前(Write/Writeの競合その2)のNODE1の状
況と全く同じである。
NODE1に関しても、主な変化は1つ前(Write/Writeの競合その2)のNODE2の状
況と同じである。
ここでのポイントはNODE1のカレント・ブロックとPast Image(PI)の内容が
異なっている点である。Past Image(PI)はあくまで、他のNODEから排他の
カレント・モードでのブロック要求があった際に、ロックダウンが発生して
初めて、カレント・ブロック(XCUR)のコピーが作成される。
次に、NODE2で再度UPDATE(Write)を行ってみる。ここでは特にX_TO_NULLと
TCHの値に注目して頂きたい。
**********************************[Write/Writeの競合その4]***
□NODE2でUPDATE(Write)を実行
SQL> update test set text='ddddd' where id1=3;
<<NODE1の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL TCH ------------- --------------- ---------- -------- ---------- ---------- TEST scur 257 5E5B6000 0 1 TEST cr 258 5E5A6000 2 1 TEST pi 258 5E5AC000 1 1 TEST_IDX scur 1170 5E5AE000 0 2
<<NODE2の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL TCH ------------- --------------- ---------- -------- ---------- ---------- TEST scur 257 5E5B4000 0 1 TEST xcur 258 5E5AA000 1 1 TEST pi 258 5E5AC000 1 1 TEST_IDX scur 1170 5E5AE000 0 2
NODE1のカレント・ブロックがCRブロックにロックダウンして、X_TO_NULL、
TCHの値がカウントアップされている(BAが5E5A6000のブロック)。また、こ
れに伴って。Past Image(PI)の内容が更新されている。ただし、Past Image
(PI)のX_TO_NULL、TCHの値はカウントアップされていない。
では、なぜTCHがカウントアップされないのか?
Past Image(PI)の役割は、あくまでもリカバリ時に使用されるブロックの
ため、再利用性は低い。また、今回の検証では強制的にWrite/Writeの競合を
発生させているが、本来、Past Image(PI)=Write/Writeの競合と考えれば
、PIがデータベース・バッファ上にあるほどWrite/Writeの競合が発生してお
り、パフォーマンス上は望ましくないことが分かる。前回の検証でもWrite/W
riteの競合でのパフォーマンスの劣化は顕著に現われた。このような観点か
らはTCHの値がカウントアップされないのは納得がいく。
※TCHに関する詳しい検証は “Oracle9iに関する検証8~” をご参照ください。
では、またまたNODE1でUPDATE(Write)を行ってみる。
**********************************[Write/Writeの競合その5]***
□NODE1でUPDATE(Write)を実行
SQL> update test set text='eeeee' where id1=2;
<<NODE1の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL TCH ------------- --------------- ---------- -------- ---------- ---------- TEST scur 257 5E5B6000 0 1 TEST xcur 258 5E5A4000 2 1 TEST cr 258 5E5A6000 2 1 TEST pi 258 5E5AC000 1 1 TEST_IDX scur 1170 5E5AE000 0 3
<<NODE2の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL TCH ------------- --------------- ---------- -------- ---------- ---------- TEST scur 257 5E5B4000 0 1 TEST cr 258 5E5AA000 2 1 TEST pi 258 5E5AC000 1 1 TEST_IDX scur 1170 5E5AE000 0 2
NODE1の排他のカレント・ブロック(XCUR)のX_TO_NULLの値が2から始まって
いる。なぜか?なぜか?と考えても良い検証案は浮かびませんでした。
ちなみに、この後も、Write/Writeの競合を繰り返すとカレント・ブロック(
XCUR)のX_TO_NULLの値が増えつづけていった。
しかし、今回のインデックス検索でのUPDATEを全件検索に変えて試したとこ
ろ、上記の様にX_TO_NULLの値が2から始まる事はなく、X_TO_NULLの値が増え
続ける事は無かった。
Oracleのマニュアルにも以下のような記載があるので、この列の値自体が正
しいという保証はないのちょっと気になるところである。実際にOracleの10g
からは無くなっている。
<Oracleのマニュアルより抜粋>--------------------------------------- X_TO_NULL: 別のインスタンスとの競合による排他モードからNULL モードへのPCM ロック 変換の回数。この列は廃止されたが、旧バージョンとの互換性を保つために 残されている ---------------------------------------------------------------------
では、最後にデータベース・バッファ上のPast Image(PI)を全て消して、
続X$BHに関する検証を終わりにしたい。
*************************************************************
□NODE1でチェックポイントを発生させる
SQL> alter system checkpoint; システムが変更されました。
Past Image(PI) → CRブロック
以上、快晴の茅ヶ崎にて