続 X$BH に関する検証 その9
<続 X$BH に関する検証 ~その9~>
ペンネーム ちょびひげ
これまで、「単一サーバ」、「単一セッション」の環境で、データベース・
バッファ上のオブジェクトの状態(ステータス)を詳細に見てきた。
今回からは、RAC(Real Application Cluster)の環境で、オブジェクトの状態
(ステータス)がどのように変化していくのかを見ていく。検証を始める前
に、GCS(グローバル・キャッシュ・サービス)について簡単にご説明する。
GCSとは
複数ノードでデータベース・バッファ上のデータを共有する為には、自分が
使いたいデータ・ブロックが、「他のインスタンスに存在するか」、「更新
されているか」、というような確認を行う必要がある。この確認をマスター
ノードに対して行う。マスターノードはハッシングによって決定される。
マスターノードはGCSを提供している。そしてこのサービスを司るのがLMSプ
ロセスであり、GCSメッセージの処理やデータベース・バッファの操作を行っ
ている。つまり、データベース・バッファ上のデータを共有ために、マスタ
ーノードへの問い合わせが増えるほど、LMSプロセスへの負荷が高くなる。そ
のような環境では、マスタノードのLMSプロセス数を増やすことにより、パフ
ォーマンスの向上が期待出来る。ユーザからの問い合わせが多いので、対応
を行う窓口を増やすわけである。
このようなGCSへの問い合わせ処理の流れを考えた場合、RACのパフォーマン
ス向上の為に重要となるのは、いかにマスターノードへの問い合わせを減ら
してローカルのデータベース・バッファ内で処理を行うか、という点である。
ちなみにローカルのデータベース・バッファ内での処理は共有のカレント・
ブロック(SCUR)により実現されている。※SCURに関しては後述
では、実際に検証を行って見て行こう。まず、初めにRAC構成で発生する競合
の種類を考えて見ると以下の4つのパターンが考えられる。
1. Read/Read の競合 2. Read/Write の競合 3. Write/Readの競合 4. Write/Write の競合
今回は上記のWrite/Write競合を除いた、3つのケースを見ていく。
検証環境は以下の通りである。
*************************************************************
□環境(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
まずは、最も基本的なRead/Read の競合の場合である。
***********************************[Read/Read の競合その1]***
□NODE1でSELECTを実行
SQL> select * from test;
<<NODE1の状況>>
OBJECT_NAME STATE DBABLK BA ------------------------------ --------------- ---------- -------- TEST scur 257 5E5E4000 TEST scur 258 5E5DA000
□データベース・バッファの状況を確認したSQL文
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 , dbablk , ba from x$bh b , dba_objects o where b.obj = o.data_object_id and o.object_name like 'TEST%' group by o.object_name, state , dbablk , ba order by dbablk;
[Read/Read の競合その1]
以下が、NODE1 でSELECTを行った場合の流れである。
1. 自ノードのデータベース・バッファ上に必要なブロックが載ってない事を 確認 2. マスターノードのLMSに、他のノードのデータベース・バッファ上に欲し いブロックが載っているかどうかを問い合わせる 3. どのノードにも必要なブロックが載っていない事を確認 4.全件検索なので、最初に、セグメントヘッダ・ブロックをディスクからデ ータベース・バッファへ共有のカレント・ブロック(SCUR)として読込み 5. データ・ブロックをカレント・ブロック(SCUR)として読込み
SCUR(共有カレント・ブロック)はRACの構成で初めて出てきたステータスで
ある。SCURは、文字通り複数のノードでカレント・ブロックを共有できる状
態を現す。
全てのノードでブロックへのアクセスが集中(SELECTの競合)したとしても
ノード間でのブロックの転送は発生しない。なぜなら、ローカルのデータベ
ース・バッファにカレント・ブロックを保持している為、マスターノードに
問い合わせを行わずとも、データへのアクセスが可能だからである。
***********************************[Read/Read の競合その2]***
□NODE2でSELECTを実行
SQL> select * from test;
<<NODE2の状況>>
OBJECT_NAME STATE DBABLK BA ------------------------------ --------------- ---------- -------- TEST scur 257 5B5CE000 TEST scur 258 5B5C8000
<<NODE1の状況>>
OBJECT_NAME STATE DBABLK BA ------------------------------ --------------- ---------- -------- TEST scur 257 5E5E4000 TEST scur 258 5E5DA000
[Read/Read の競合その2]
まず、マスターノードに対して、いずれかのノードのデータベース・バッフ
ァ上に必要なブロックが載っているかどうかの確認を行う。すでにNODE1のデ
ータベース・バッファ上に必要なブロックが載っている為、NODE1からNODE2
にSCURブロックの転送がインターコネクト経由で行われる。当然、ディスク
I/Oはゼロ(0)である。
では最後にRead/Write の競合をみる。
**********************************[Read/Write の競合その1]***
□NODE1でSELECTを実行
SQL> select * from test;
<<NODE1の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL ------------- --------------- ---------- -------- ---------- TEST scur 257 5E5DA000 0 TEST scur 258 5E5D6000 0
[Read/Write の競合その1]
最初のNODE1でのSELECT(Read)は先程と同様の状態である。
**********************************[Read/Write の競合その2]***
□NODE2でUPDATEを実行
SQL> update test set id2=1 where id2=2;
<<NODE2の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL ------------- --------------- ---------- -------- ---------- TEST scur 257 5E3A4000 0 TEST xcur 258 5E3A0000 0 TEST cr 258 5E3A2000 0
<<NODE1の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL ------------- --------------- ---------- -------- ---------- TEST scur 257 5E5DA000 0 TEST cr 258 5E5D6000 1
[Read/Write の競合その2]
次にNODE2からのUPDATE(Write)を行うと、以下のようにステータスが変化
している。
NODE1 | NODE2 | [転送] SCUR -→ XCUR ↓ | CR |
[ロックダウン]
まず、NODE1 のデータ・ブロックでステータスがSCURからCRへのロックダウ
ンが行われる。次にNODE1 からNODE2にSCURのセグメント・ヘッダとXCURのデ
ータ・ブロックが転送される。最後にNODE2で「単一サーバ」、「単一セッシ
ョン」の場合と同様にCRブロックを作成した後、UPDATEを行う。
ロックダウンとは?
上記の結果としてX_TO_NULL列を追加している。この列はブロックのステータ
スがカレントモードから別のステータスに変化した場合にカウントアップさ
れる。上記の例では、共有のカレントモード(SCUR)から読取一貫性のモー
ドに変化している為に、X_TO_NULL列の値がカウントアップされ1となってい
る。この動きをロックダウンという。
ただし、Oracleのマニュアルには以下のような記載があるので、この列の値
自体が正しいという保証はない。
<Oracleのマニュアルより抜粋>--------------------------------------- X_TO_NULL: 別のインスタンスとの競合による排他モードからNULL モードへのPCM ロック 変換の回数。この列は廃止されたが、旧バージョンとの互換性を保つために 残されている ---------------------------------------------------------------------
次はWrite/Read の競合をみる。これも順次動きを追って、見ていきたい。
**********************************[Write/Read の競合その1]***
□NODE1でUPDATE(Write)を実行
SQL> update test set id2=1 where id2=2;
<<NODE1の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL ------------- --------------- ---------- -------- ---------- TEST scur 257 5E5CA000 0 TEST xcur 258 5E5C0000 0 TEST cr 258 5E5C2000 0
[Write/Read の競合その1]
まず、CRブロックは、「単一サーバ」、「単一セッション」の場合でも作成
された通り、全件検索でのUPDATEで作られるブロックである。SCURはセグメ
ントヘッダで、このヘッダの更新は行っていないので、共有のカレント・ブ
ロックとなっている。それに対して、データ・ブロックは更新をおこなって
いるので、排他のカレント・ブロック(XCUR)となっている。
ではもう一方のノード(NODE2)からSELECT(Read)を行う。
**********************************[Write/Read の競合その2]***
□NODE2でSELECT(Read)を実行
SQL> select * from test;
<<NODE2の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL ------------- --------------- ---------- -------- ---------- TEST scur 257 5B5CE000 0 TEST cr 258 5B5C8000 0
セグメントヘッダはSCURでread/read の競合
cr はxcur から情報をもらって一時的に使用
<<NODE1の状況>>
OBJECT_NAME STATE DBABLK BA X_TO_NULL ------------- --------------- ---------- -------- ---------- TEST scur 257 5E5CA000 0 TEST xcur 258 5E5C0000 0 TEST cr 258 5E5BE000 0 TEST cr 258 5E5C2000 0
[Write/Read の競合その2]
まず、両ノードでのSCURブロックを見て欲しい。セグメントヘッダへの更新
は行われていないので、共有のカレント・ブロックを両ノードで保持してい
る状態である。
次に両ノードでCRブロックがあるのが分かる。初めにNODE1でCRブロックが作
成され作成されたCRブロックがNODE2へ転送されている状態である。このあと
は何度、NODE2からSELECTを行っても、上記と同様に以下のCRブロックの転送
を繰り返す。
[NODE1 でデータ・ブロックのCRブロックを作成]
↓
[NODE1からNODE2へのCRブロックを転送]
【競合発生時のレスポンスダウン】
最後に、それぞれの競合が発生した場合のEPS(Executions Per Second)を
表示する。
1ブロックに対してアクセスを行う検証を行っているので、100%競合が発生
している状態である。あまり、正確な値とは言えないが、どの程度パフォー
マンスが低下するかの目安として欲しい。トランザクション数は各ノードと
も1セッションである。
※EPS値・・・Execution Per Secondの略称で、単位時間(秒)あたりのSQL実 行数を現す。処理性能の相対評価の指針として使用している。
◇同一の位置ブロックに対して以下の処理を行う。
[Read処理] [Write処理] ^^^^^^^^^^ ^^^^^^^^^ select処理 update処理 ← ↓ ↑ commit処理 →
評価の基準となる、EPS値を取得した所以下の様になった。
****************************************** NODE1 EPS --------------------------------------- Read(SELECT) 処理 10000 Write(UPDATE)処理 416 ******************************************
競合させた場合のEPS値である。
※カッコ内は規準を1とした場合の比較値
******************************************
NODE1 / NODE2 EPS(NODE1) EPS(NODE2) ------------------------------------------------- Read/Read 処理 10000[1.00] 10000[1.00] Write/Read 処理 250[0.60] 714[0.07] Write/Write処理 175[0.40] 192[0.46] ******************************************
Read/Readでの競合では全くレスポンスの悪化はなく、やはり、書込み処理が
入った競合で、レスポンスの悪化が見られる。ロックダウンやCRブロックの
作成ブロックの転送の負荷が大きく影響していると言える
次回はWrite/Writeの競合を見ていきたい。
以上、自転車の事故にも気をつけてね!茅ヶ崎にて