続 X$BH に関する検証 その3
∽ 前回の検証の訂正 ∽
申し訳ありません。前回の検証で取得したダンプの結果が間違っていました
ので訂正します。
【正】が正しく
【誤】が前回間違っていた部分です。
SQL> alter session set events 'immediate trace name buffers level 6';
◆XCURブロック
【正】更新後データ:(列1,列2,列3) = (1,2,’insight)
【誤】更新後データ:(列1,列2,列3) = (2,2,’insight)
tl: 17 fb: --H-FL-- lb: 0x2 cc: 3 col 0: [ 2] c1 02 ← ID1 = 1 col 1: [ 2] c1 03 ← ID2 = 2 col 2: [ 7] 69 6e 73 69 67 68 74 ← TEXT = insight tab 0, row 2, @0x1f65
◆CRブロック
【正】更新後データ:(列1,列2,列3) = (2,2,’insight)
【誤】更新後データ:(列1,列2,列3) = (1,2,’insight)
tl: 17 fb: --H-FL-- lb: 0x0 cc: 3 col 0: [ 2] c1 03 ← ID1 = 2 col 1: [ 2] c1 03 ← ID2 = 2 col 2: [ 7] 69 6e 73 69 67 68 74 ← TEXT = insight
┏─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━┓
●【 Oracle 検証生活 】 ●
┗─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━┛
<続 X$BH に関する検証 ~その3~>
ペンネーム ちょびひげ
前回は「単一サーバ」、「単一セッション」でX$BH表のSTATE列の情報を見る
事により以下の点を確認した。
・SELECT、INSERT処理を行ってもCRブロックは作成されない。
・UPDATE処理を行った場合にはCRブロックが作成される。
今回は同じUPDATE処理でもCRブロックが作成されないケースが存在するので、
その状況を見てみよう。ちなみにDELETE処理はUPDATEとほとんど同様の動き
である。
環境は前回と同様に以下の通りである。
*************************************************************
◆環境
Linux 2.4.2-2
Oracle9i EE Release 9.2.0.1.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
前回のUPDATE処理では以下のSQL文を実行した。
SQL> update test set id1 = 1 where id2 =2;
このSQLではWHERE句の条件として”ID2″列を指定している。”ID2″列にはイン
デックスが作成されていないので、全件検索を行っての更新処理となってい
る。
そこで、今回はWHERE句の条件として、インデックスが作成されている”ID1″
列を指定して、インデックス検索による更新を行ってみる。
*************************************************************
◇UPDATE処理を実行
SQL> update test set id1 = 1 where id1 =2;
※インデックスが使用されるようにWHERE句の条件にID1列を指定している
◇データベース・バッファ上の状態
SQL> select o.object_name ,decode(state,0,'free',1,'xcur',2,'scur',3,'cr', 4,'read',5,'mrec' ,6,'irec',7,'write',8,'pi') STATE , count(*) BLOCK from x$bh b , dba_objects o where b.obj = o.data_object_id and o.object_name = 'TEST%' group by o.object_name, state OBJECT_NAME STATE BLOCKS -------------------- ----- ---------- TEST xcur 2 TEST_IDX xcur 1
ご覧の通りCRブロックは作成されない。インデックスも1ブロックだけデータ
ベース・バッファ上にある状態である。なぜか???。。。
ちなみに、前回行った全件検索での更新処理でも、更新対象のデータが無い
場合はCRブロックは作成されない。
*************************************************************
更新対象がない全件検索でUPDATE処理を行った時のデータベース・バッファ
の状態
SQL> update test set id1=3 where id2=5; ※ID2 にはインデックスはなく、ID2=5 のデータは存在しない。 0行が更新されました。 OBJECT_NAME STATE DBARFIL DBABLK BA -------------------- ----- ---------- ---------- -------- TEST xcur 1 70913 54D28000 TEST xcur 1 70914 54D20000
いままでのCRブロックが作成されるケースは以下の通りである。
CRブロックが作成されるケース(単一セッション) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UPDATE SELECT INSERT ---------------- ------------------- --------- -------- 全件検索 ○(更新対象あり) × ― インデックス検索 × × ―
「単一のセッション」の場合は全件検索のUPDATE処理でのみCRブロックが作
成されるということになる。
つまり、なぜ全件検索のUPDATE処理時にCRブロックが出来るか?が疑問であ
る。
本来、CRブロックは読取一貫性のブロックではあるが、「単一セッション」
にもかかわらずCRブロックが出来る理由は、CRブロックを読みに行く為では
なく、ロールバック情報の作成やロックの機能を満たす必要がある為ではな
いだろうか?
インデックス検索の更新ではCRブロックが出来ないのは、インデックスから
更新対象のROWIDを特定する事ができるので、行単位で更新処理を行なう為に
CRブロックを作る必要がないのかも知れない。
では最後に、カレント・ブロックの更新の仕組みが全件検索とインデックス
検索の場合で大きく異なっている点を見てみる。
以下は、インデックス検索時のカレント・ブロックのバッファ・アドレス(
BA:データベース・バッファ上での場所)の変化である。
*************************************************************
インデックス検索での更新時:
【更新前】
OBJECT_NAME STATE DBABLK BA -------------------- ----- -------- -------- TEST xcur 18716 54D0E000 ← 更新対象ブロック TEST_IDX xcur 18724 54D04000
【更新後】
OBJECT_NAME STATE DBABLK BA -------------------- ----- -------- -------- TEST xcur 18716 54D0E000 ← 更新対象ブロック TEST_IDX xcur 18724 54D04000 ※BAに変化なし
カレント・ブロックのアドレス(BA)が変化していない。つまり、直接カレン
ト・ブロック内のデータの更新を行っている。
次に全件検索時のXCURブロックのバッファ・アドレス(BA)の変化をみて頂き
たい。
*************************************************************
全件検索での更新時:
【更新前】
OBJECT_NAME STATE DBABLK BA -------------------- ----- -------- -------- TEST xcur 18717 54C3A000 ← 更新対象ブロック
【更新後】
OBJECT_NAME STATE DBABLK BA -------------------- ----- -------- -------- TEST xcur 18717 551F2000 ← 更新対象ブロック TEST cr 18717 54C3A000 ※BAに変化あり ↑ 変更前のカレント・ブロックのBA
カレント・ブロックのアドレス(BA)が変化している事が分かる。また、更
新前にカレント・ブロックだったアドレス(BA)には、CRブロックとなって
いる。つまり、全件検索時の更新処理の流れは以下のようになる。
(1)54C3A000(BA)にあったカレント・ブロック(XCUR)が 551F2000(BA) にコピーされる。 (2)元のカレント・ブロックがCRブロックとなる。 (3)XCURへの更新処理を行なう。
次回は「単一サーバ」、「複数セッション」の場合の動きを見ていきたい。
以上、日暮れ間際の茅ヶ崎にて