バッファキャッシュとは
バッファキャッシュとは可能な限り低速なDISK I/Oの量を減らしメモリ上で処理を完了させ高速化するための目的で確保されるメモリ領域で、 ORACLEデータベース起動時に確保されるSGAと呼ばれるメモリ内に領域が確保されています。 本ページではバッファキャッシュに関連するチューニング方法や確認方法をまとめています。ORACLEのバッファキャッシュ基礎知識
・バッファキャッシュのサイズには限りがあるため空きがなくなると基本的にはLRU(Least Recently Used)アルゴリズムによって、最も参照頻度が低いブロックからバッファキャッシュから追い出されていきます(エイジアウト)・エイジアウトのロジックは完璧なLRUアルゴリズムではなく、ORACLE独自のロジックが含まれています。 例えば、バッファキャッシュの2%のサイズを超えるセグメントはラージセグメントとして扱われ、ラージセグメントのフルスキャンにより読み込まれたブロックは既存のバッファキャッシュ上のブロックが多くエイジアウトされてしまうことを防ぐため最もエイジアウトされやすい位置に登録されます。 このため、バッファキャッシュに空きがない状態で巨大なテーブルのフルスキャンを実施してもほぼキャッシュに乗らない場合があります。
・バッファキャッシュ上のブロックはxcur(最新で更新可能)、cr(参照モード)等のステータスを持ちます。同一ブロックに対してxcurステータスのブロックは一つだけですが、crモードのブロックは複数保持する場合があります。 これは異なるSCNの状態のcrモードのブロックを保持することによってUNDOを参照せずにデータを戻すことができるためです。
また、RAC環境においてはさらにscur(複数ノード間で共有可能(sharable)なcurrentブロック)や、PI(Past Image、更新された後に他ノードでさらに更新済みのブロック)等のRAC固有のステータスもあります。
バッファキャッシュを経由しないダイレクト処理
大量データのロード等により大量のブロックを登録する場合バッファキャッシュへの登録やバッファキャッシュからのエイジアウト等の処理自体が遅延の原因になりえます。 こういったケースの場合バッファキャッシュ関連の処理を全てスキップして直接データファイルに登録するダイレクト処理を利用することで従来型処理よりも高速に処理することができます。 ただし、バッファキャッシュに乗らないことが災いして後続処理がDISKアクセス多発により遅延する可能性もあるため総合的にみると従来型処理で処理したほうがよいケースもあります。・direct read
ダイレクトリードが使用されるのは主にパラレル処理、ラージセグメントに対するフルスキャン(11g~、デフォルト10%で隠しパラメータで制御可能)、direct=yを指定したexp、expdpとなります。
・direct write
ダイレクトライトが使用されるのは主にinsert /*+ append */ into XXX select、insert /*+ APPEND_VALUES */ into XXX values(11g~)、sqlldrのdirect=yです。 ダイレクトライトは既存ブロックに対する更新ができないためupdateやdelete等はダイレクト処理できません。また、insertで追加されるブロックは必ず新規ブロックとして追加されるので APPEND_VALUESヒント付のinsert文を配列等を使用せずに1行ずつループするとデータサイズが膨れ上がり無駄な空き領域が大量にできるので注意が必要です。
ORACLEの外側のキャッシュ
- OSのファイルキャッシュOSでもORACLEと同じように高速化を目的としたファイルシステムのキャッシュ機能が動作しており、 WINDOWS以外のOSでファイルシステム上にデータファイル等を配置している場合はデータがORACLEのバッファキャッシュとOSのファイルキャッシュで2重管理され無駄な処理をさせることになるため RAWデバイス(ASM含む)にデータを配置したほうが理想的です(ただし、ASMはASMインスタンスを介してファイルアクセスされるという別のオーバヘッドがあります)。 ファイルシステム上にデータファイルを置いている場合はOSファイルキャッシュによりORACLEのバッファキャッシュ上にブロックがない状態でも性能が早くなる可能性もあるため性能検証には注意する必要があります。
- ストレージ機器のキャッシュ
ほとんどのストレージ機器はキャッシュ機能を備えており、キャッシュによって主に書き込み時のレスポンス向上等を実現しています。ストレージのキャッシュ機能を利用することでパフォーマンスが向上することは間違いないですが、 キャッシュを有効にすることはOS側からのDISK書き込み要求に対して実際にDISKへ書き込みする前にレスポンスを返す(write back方式)ことになるためストレージの障害時にはデータが整合性が取れなくなりリカバリが必要になる可能性が高くなります。 キャッシュ機能はこの欠点にも目をつむれる位の効果がありますが、少なくともアーカイブログ(パフォーマンスよりもデータ保全を重視するならばREDOログも)はwrite backではなくwrite throughで書き込むようにするか別のストレージに配置したほうが無難です。
関連システム統計
バッファキャッシュに関連する主なシステム統計としては以下のようなものがあります。(バージョンによっては存在しないものがあります)consistent gets from cache consistent gets - examination consistent gets direct physical reads physical reads cache physical reads direct physical read IO requests physical read bytes db block changes consistent changes recovery blocks read physical writes physical writes direct physical writes from cache physical write IO requests physical write bytes physical writes non checkpoint summed dirty queue length DBWR checkpoint buffers written DBWR thread checkpoint buffers written DBWR tablespace checkpoint buffers written DBWR parallel query checkpoint buffers written DBWR object drop buffers written DBWR transaction table writes DBWR undo block writes DBWR revisited being-written buffer DBWR make free requests DBWR lru scans DBWR checkpoints prefetch clients - keep prefetch clients - recycle prefetch clients - default prefetch clients - 2k prefetch clients - 4k prefetch clients - 8k prefetch clients - 16k prefetch clients - 32k change write time redo synch writes redo synch time exchange deadlocks free buffer requested dirty buffers inspected pinned buffers inspected hot buffers moved to head of LRU free buffer inspected commit cleanout failures: write disabled commit cleanout failures: block lost commit cleanout failures: cannot pin commit cleanout failures: hot backup in progress commit cleanout failures: buffer being written commit cleanout failures: callback failure commit cleanouts commit cleanouts successfully completed recovery array reads recovery array read time CR blocks created current blocks converted for CR switch current to new buffer write clones created in foreground write clones created in background write clones created for recovery physical reads cache prefetch physical reads prefetch warmup prefetched blocks aged out before use prefetch warmup blocks aged out before use prefetch warmup blocks flushed out before use physical reads retry corrupt physical reads direct (lob) physical reads direct temporary tablespace physical writes direct (lob) physical writes direct temporary tablespace cold recycle reads shared hash latch upgrades - no wait shared hash latch upgrades - wait physical reads for flashback new total number of slots background checkpoints started background checkpoints completed number of map operations number of map misses lob reads lob writes lob writes unaligned table lookup prefetch client count
バッファキャッシュに乗っているブロックを確認する方法
現在バッファキャッシュに乗っているブロックの情報はV$BHより確認可能であり、 以下のようなSQLにより各セグメントがどの程度バッファキャッシュ上にあるか確認することができます。 (OBJD(data_object_id)列はdba_objectsのdata_object_id列に対応しています)select objd,count(*) from v$bh where status <> 'free' group by objd;
マニュアル
・概要・パフォーマンス・チューニングガイド