2010年4月9日金曜日

oracle データベースバッファキャッシュ2

食中毒になった。色々出てしまった・・。あんなに辛かったのは小6の時に40度の熱が出て以来だ。
来週の水曜の勉強会のために調べた内容を一部公開!

----------------------------------------------------------
■ データベースバッファキャッシュの構成
----------------------------------------------------------
データベースバッファキャッシュは以下の2つのリストで管理されています。
・ 書き込みリスト
・ LRUリスト

書き込みリストは使用済みバッファを保持します。
使用済みバッファとは、「修正されたが、まだディスクに書き込まれていないデータを含むバッファ」を指します。
LRUリストは、使用可能バッファ、使用中バッファおよび書込みリストに移動していない使用済バッファを保持します。
使用可能バッファとは、空、もしくはデータファイルと同期がとれているブロックが含まれるバッファを指します。
使用中バッファとは、現在アクセスされているバッファを指します。
LRUリストに含まれる使用済みバッファは特定のタイミングで書き込みリストへ移動します。

LRUリストにはLRU側とMRU側が存在し、LRU側であるほど、そのバッファに含まれるブロックの要求頻度が低く、
MRU側であるほど、そのバッファに含まれるブロックの要求頻度が高いことを表します。

----------------------------------------------------------
■ データベースバッファキャッシュの仕組み
----------------------------------------------------------
ユーザープロセスからデータの要求があると、まず、サーバープロセスは、データベースバッファキャッシュ内のデータを検索します。
キャッシュ内にデータが見つかった場合(キャッシュヒット)、プロセスは、キャッシュからデータを返します。
キャッシュヒットが発生すると、そのブロックは、LRUリストのMRU側へ移動します。

さらに多くのバッファがMRU側へ移動されるにつれて、アクセスが古いバッファはLRU側へ移動していきます。
(使用頻度の低いバッファほどLRU側へ移動しやすいです)

キャッシュ内にデータが見つからなかった場合(キャッシュミス)、
プロセスはディスク上のデータファイルからキャッシュ内のバッファにデータブロックをコピーする必要があります。
データブロックをコピーするには、コピーしたブロックを保持するためのバッファ(使用可能バッファ)を見つける必要があります。
その際、プロセスはLRUリストのLRU側から使用可能バッファの検索を行います。
検索は、以下の何れかの条件を満たすまで続きます。
・ 使用可能バッファを見つける
・ 検索したバッファ数が制限閾値に達する
LRUリスト検索時に使用済みバッファを見つけた場合、そのバッファを書き込みリストへ移動してから検索を続けます。
この際、書き込みリストのサイズが閾値を越えると、書き込みリスト上の使用済みバッファがDBWRによってディスクに書き込まれます。
使用可能バッファが見つかると、プロセスはディスクからバッファにデータブロックを読み込んで、バッファをLRUリストのMRU側へ移動します ※1

使用可能バッファが見つからず、検索したバッファ数が制限しきい値に達すると、プロセスはLRUリストの検索を停止し、データベースライターに使用済みバッファをデータファイルに書き込むよう指示します。
この際、使用済みバッファの書き込みリストへの移動は発生せず、直接LRUリストからディスクへの書き込みが行われます。
こうすることで、使用可能バッファを確保し、そこにデータブロックを読み込みます。

※1
厳密には、インデックススキャンによるランダムリードが実施された場合はMRU側とLRU側の境目にあるコールドポインタという位置に挿入されます。
フルスキャンによるシーケンシャルリードが実施された場合はLRU側に挿入され、次の瞬間には破棄される状態となります。
こういった仕組みにより、本当に重要なデータがLRUリストから押し出されることを防ぎます。
-------------------------------------------------------------------------------------
実際は図もいれてるからもっとわかりやすいだよ!でも掲載の仕方が分からない。みんなすごいなー

あと、まえの投稿でデータベースバッファキャッシュのキャッシュを消す方法を書いたけど、正確にsqlの性能を調べるには、ディクショナリキャッシュ、ライブラリキャッシュの情報も消す必要があるはずなので、以下のコマンドも実行したほうが良い気がしてきた。

ALTER SYSTEM FLUSH SHARED_POOL
(共有プールのクリア)

本番環境で・・(略

0 件のコメント:

コメントを投稿