
はじめに
今回はOracle RACにおけるキャッシュフュージョンについて説明します。キャッシュフュージョンとは各インスタンスが持っているデータに関する処理に一貫性を持たせるための機能であり、複数インスタンスに対する各種DML処理を高速化する仕組みとなります。一方で複雑なノード間処理が発生することにより、逆に性能劣化であったり思わぬトラブルが生じることが少なくありませんので、しっかり仕組みを理解して適切な設計およびトラブル対応をできるようにしておくことが大切です。
Oracle RACの基本的な内容については下記の記事に記載しているので、合わせて見てもらえればと思います。
Oracle RACの仕組みを理解しよう ~ClusterwareおよびASMで実現する機能について~
Oracle RACの仕組みを理解しよう ~データベース接続および負荷分散の仕組みについて~
データ一貫性を保つための仕組み
Oracle RAC構成では、各種DML処理によるデータの一貫性を維持するために、Global Resource Directory (GRD) が管理するデータブロックの最新情報を利用しています。
この情報を基に、Global Enqueue Service (GES) と Global Cache Service (GCS) がデータのロックやキャッシュの管理を行い、複数インスタンス間でのデータ整合性を確保します。

各種用語について、以下に説明します。
| 用語 | 説明 |
|---|---|
| GRD (Global Resource Directory) | データブロックの状態を記録する内部データベースです。本データの保存にメモリ容量を使用するため、Oracle RACを使用する場合は SGAを約10%多めに確保することが推奨されます。 |
| GES (Global Enqueue Service) | ローカルおよびグローバルで共有されるエンキュー処理を調整するサービスです。デッドロック検知やリクエストタイムアウトの制御も担当します。 |
| GCS (Global Cache Service) | 複数のOracle RACインスタンスのバッファキャッシュ内データブロックへのアクセスを調整し、キャッシュ一貫性を提供する主要なグローバルリソースです。 – キャッシュフュージョンを実装する制御プロセスであり、最新のデータブロック情報の把握やインスタンス間のブロック転送を行います。 – LMSn(Global Cache Service Processes)や LMD(Global Enqueue Service Daemon)などのバックグラウンドプロセスによって実装されます。 |
| LMON (Global Enqueue Service Monitor) | クラスタ全体を監視し、グローバルリソースを管理します。インスタンスやプロセスの異常終了、およびGESやGCSに関連するリカバリも担当します。 |
| LMD (Global Enqueue Service Daemon) | Global Enqueue Serviceのリソース要求を管理するリソースエージェントプロセスとなります。デッドロック検出およびGlobal Enqueue Serviceの要求も処理します。 |
| LCK0 (Instance Enqueue Process) | ライブラリキャッシュ要求など、データブロック以外のリソースに対する要求を管理するプロセスです。 |
| LMSn (Global Cache Service Process) | インスタンス間リソースを制御し、キャッシュフュージョンを実現する主要プロセスです。GCS要求やブロック転送などのGCS関連メッセージの送受信および処理を担当します。 |
キャッシュフュージョンの仕組み
ここでは、GCSによるキャッシュフュージョンの仕組みを説明します。
例として、片方のインスタンスで更新されたデータブロックを、別のインスタンスから参照する流れを示します。また、更新処理が Commit済みかどうか によって挙動が異なるため、それぞれの場合に分けて解説します。
片ノードにおける更新処理がCommitされている場合

- インスタンスAでデータブロックを更新
インスタンスAに対してUpdate文を実行し、該当するデータブロック(Current Block)を更新します。 - Update文をコミット
CommitによりブロックはCurrent状態として確定します。 - インスタンスBで参照要求を実施
インスタンスBに対してSelect文を実行し、1で更新されたデータにアクセスします。 - GCSによるリソースマスターへの問い合わせ
GCSは参照要求のあったブロックのホルダーをリソースマスターに問い合わせます。
– ホルダー:最新のブロックを保持しているインスタンス
– リソースマスター:最新のブロックを保持しているインスタンスを把握しているインスタンス
※今回の例ではインスタンスAがリソースマスターかつホルダーですが、別々のインスタンスになる場合もあります。 - ブロック転送の指示
インスタンスAがホルダーであるため、GCSがインスタンスBにブロック転送を指示します。 - Current Blockの転送
インスタンスAからインスタンスBに最新のCurrent Blockが転送されます。 - 転送完了通知
インスタンスAがブロックを転送したことをインスタンスBに通知します。 - インスタンスBで参照完了
インスタンスBは転送されたCurrent Blockを受け取り、最新データを参照します。
片ノードにおける更新処理がCommitされていない場合

- インスタンスAでデータブロックを更新(Commit前)
Update文を実行し、該当データブロックをインスタンスAのバッファキャッシュ内でCurrent状態に更新します。 - インスタンスBで参照要求を実施
インスタンスBに対してSelect文を実行し、1で更新されたデータを読み取ろうとします。 - GCSによるリソースマスターへの問い合わせ
GCSが参照要求のあったブロックのホルダーをリソースマスターに問い合わせます。 - ブロック転送の指示
ホルダーであるインスタンスAに、GCSがCRブロックの転送を指示します。 - CRブロックの生成
インスタンスAはUNDO情報を利用して、読み取り一貫性を保持したCRブロック(Consistent Read Block)を作成します。 - CRブロックの転送
CRブロックがインスタンスBに転送されます。 - 転送完了通知
インスタンスBはCRブロックを受け取り、GCSを介してインスタンスAに転送完了を通知します。 - インスタンスBで参照完了
インスタンスBは転送されたCRブロックを使用して、読み取り一貫性を保ったデータを参照します。
まとめ
本記事では、Oracle RACにおけるキャッシュフュージョン(Cache Fusion)とデータブロック転送の流れを解説しました。
キャッシュフュージョンは、複数インスタンス間でデータの一貫性を保ちながら高速なDML処理を可能にする仕組みです。GRDがブロック状態を管理し、GESやGCSがロックや転送を制御することで、整合性のある分散処理が実現されます。
更新がCommit済みか未Commitかでブロック転送の方法が異なることも重要なポイントです。Commit済みの場合はCurrent Blockが転送され、未Commitの場合はUNDO情報を使ったCRブロックが生成されます。
この仕組みを理解することで、Oracle RACの設計やパフォーマンスチューニング、トラブル対応がより適切に行えるようになります。
参考文献
津島博士のパフォーマンス講座 第79回 Real Application Clustersの待機イベントについて
Oracle Real Application Clusters(Oracle RAC)のキモ ~Cache Fusionに注目する~

https://www.oracle.com/jp/a/ocom/docs/jp-db-technight-content/02-20170728-discussionnight-rac2.pdf


コメント