Oracle RACのキャッシュ・フュージョンとは?仕組みと3つのシナリオを徹底解説
キャッシュ・フュージョン(Cache Fusion)とは、Oracle Real Application Clusters(RAC)において、クラスタ内の複数インスタンス間でデータブロックを転送する仕組みのことです。RACアーキテクチャの中核を担う最重要機能であり、RACの性能と可用性を理解するうえで欠かせない概念です。
はじめに
Oracleの公式説明によると、RACクラスタ内の各インスタンスはそれぞれ独自のローカル・バッファ・キャッシュを持ち、そこでキャッシュ機能を実行します。しかし、複数のユーザーが異なるノードに接続している場合、あるインスタンスが所有するデータブロックに対して、別のインスタンス側のユーザーがアクセスやロックを必要とすることが頻繁に発生します。
このようなケースでは、要求元のインスタンスが保持元のインスタンスに対してデータブロックを要求し、インターコネクト機構を経由してそのブロックにアクセスします。この一連の動作こそがキャッシュ・フュージョンです。
単一インスタンスの場合の動作
キャッシュ・フュージョンを理解する前に、まずRAC以外の通常の単一インスタンス環境で、データブロックへのリクエストがどのように処理されるかを見てみましょう。単一インスタンスにおけるトランザクション処理は、おおむね次の4ステップで構成されます。
- ユーザーが最近変更されたブロックを読み取ろうとすると、そのブロック内にアクティブなトランザクションが存在する場合があります。
- トランザクションがコミット済みかどうかを判断するため、プロセスはUNDOセグメントヘッダーを読み取る必要があります。
- トランザクションが未コミットだった場合、プロセスはバッファ・キャッシュ内で、ブロック自体のデータとUNDOセグメントの情報を使って一貫性読み込み(Consistent Read:CR)版のブロックを作成します。
- UNDOセグメントがトランザクションのコミット済みを示していた場合は、プロセスは再度ブロックにアクセスし、ブロックのクリーンアウト(遅延ブロッククリーンアウト)を行い、変更内容に対するREDOを生成します。
次に、同じシナリオが2インスタンス構成のRACクラスタではどうなるのか、つまりキャッシュ・フュージョンの動作を見ていきます。
キャッシュ・フュージョンの基本概念
RACでは、同一ストレージ(ASMなど)上にある同じデータベースファイルに対して、2つ以上のインスタンスがアクセスします。各インスタンスは独自のSGAやバックグラウンドプロセスを持つため、当然ながら各インスタンスにはローカルなバッファ・キャッシュが存在します。
これらのバッファ・キャッシュはインスタンスレベルでは個別に動作しますが、データベースレベルでは融合し、単一の実体としてのグローバル・キャッシュ(Global Cache)を形成します。これにより、インスタンス間でデータブロックを共有できるようになります。これがまさにキャッシュ・フュージョンです。
キャッシュ・フュージョンは高速なIPCインターコネクトを使用し、クラスタ内のインスタンス間でキャッシュからキャッシュへの直接のデータブロック転送を行います。このブロック配送方式によりディスクI/Oが削減され、読み書きの同時実行性が最適化されます。
グローバル・キャッシュ・サービス(GCS)とバックグラウンドプロセス
この仕組みを支えているのが、インスタンス間のブロック転送を担当するグローバル・キャッシュ・サービス(GCS:Global Cache Service)です。主なバックグラウンドプロセスは以下の2つです。
- グローバル・キャッシュ・サービス・プロセス(LMSn)
- グローバル・エンキュー・サービス・デーモン(LMD)
これらのプロセスを詳しく見る前に、Oracleがデータブロックをどのように扱い、管理しているかを理解しておく必要があります。
データブロックのリソースモード
Oracleはデータブロックを「リソース」として扱います。各リソースは異なるモードで保持でき、これはデータ整合性を維持するための重要なメカニズムです。モードは、リソース保持者がデータを変更しようとしているのか、それとも読み取るだけなのかによって、次の3種類に分類されます。
- Null(N)モード:プレースホルダーとして保持されることが多いモードです。
- Shared(S)モード:他のセッションによる変更は行われず、同時共有アクセスが許可されるモードです。
- Exclusive(X)モード:保持プロセスに排他的なアクセス権を与えます。他のプロセスはリソースに書き込めませんが、一貫性読み込み用のブロックを持つことは可能です。
グローバル・キャッシュ・サービス・プロセス(LMSn)
インスタンスからブロック要求があると、GCSはメモリ上にブロックのコピーを保持しながら、他インスタンスへのブロック配送を制御します。このコピーは過去イメージ(Past Image:PI)と呼ばれます。ブロックがダーティな状態で何度も要求された場合には、1つのデータブロックに対して複数のPIが存在することもあります。
補足:データブロックを読み取る際は、必ず一貫した状態で読む必要があります。他のトランザクションが加えた未コミットの変更を読むことは許されません。
グローバル・エンキュー・サービス・デーモン(LMD)
グローバル・エンキュー・サービス(GES:Global Enqueue Service)は、Oracleのすべてのエンキュー機構の状態を追跡します。GESは、辞書キャッシュロック、ライブラリキャッシュロック、およびトランザクションに対して同時実行制御を行い、複数インスタンスからアクセスされるリソースに対してこの操作を実行します。GESはデータファイルや制御ファイルへのアクセスは管理しますが、データブロックそのものは管理対象外です。
GESが管理する主なリソースは以下のとおりです。
- トランザクションロック:トランザクションが変更処理(INSERT、UPDATEなど)を開始すると排他モードで取得されます。ロックはトランザクションがコミットまたはロールバックされるまで保持されます。
- ライブラリキャッシュロック:SQL、DML/DDL、PL/SQL、Java文の解析やコンパイル時にデータベースオブジェクト(表、ビュー、パッケージ、パッケージ本体など)が参照されると、その文を解析・コンパイルするプロセスが適切なモードでライブラリキャッシュロックを取得します。
- 辞書キャッシュロック:クラスタデータベースモードではグローバルエンキューが使用されます。クラスタ内のすべてのOracleインスタンスで、データディクショナリの構造は同一である必要があります。
- 表ロック:表全体を保護するGESロックです。トランザクションが表を変更する際に取得され、Null(N)、行共有(RS)、行排他(RX)、共有(S)、共有行排他(SRX)、排他(X)といった複数のモードで保持できます。
過去イメージ(PI)と一貫性読み込みイメージ(CR)
具体的なシナリオに入る前に、過去イメージ(PI)と一貫性読み込み(CR)イメージという2つの重要な概念を整理しておきましょう。
過去イメージ(Past Image:PI)
PIの概念はRAC環境特有のものです。あるインスタンスが更新目的でデータブロックに対する排他ロックを保持している状況を考えてみます。ここでRAC内の別のインスタンスがそのブロックを必要とした場合、保持側インスタンスはブロックをディスクに書き出す代わりに、自身のバッファ・キャッシュ内にPIを残したまま、ブロックを要求元インスタンスへ送ることができます。つまりPIとは、ブロックがディスクに書き込まれる前のデータブロックのコピーです。
一貫性読み込みイメージ(Consistent Read:CR)
あるブロックがトランザクションA1によってアクセス・変更されている最中に、別のトランザクションA2が同じブロックへのアクセス・読み取りを試みたとします。A1がまだコミットされていない場合、A2は変更されていない状態のブロックコピーが必要です。このとき、該当ブロックのUNDOデータを使ってCRコピーが作成されます。
キャッシュ・フュージョンの3つのシナリオ
キャッシュ・フュージョンの動作は、次の3つのシナリオに分けて考えることができます。
- Read-Read(読み取り−読み取り)シナリオ
- Read-Write(読み取り−書き込み)シナリオ
- Write-Write(書き込み−書き込み)シナリオ
Read-Readシナリオ
これはクリティカルではないシナリオです。ブロックを要求するインスタンスと、要求を保有するインスタンスの両方が読み取りトランザクションを行っているためです。この場合、排他ロックは発生しません。
インスタンスBがGCSに対して読み取りブロックを要求すると、GCSはブロックの所在を確認します。ブロックはインスタンスAが所有しているため、GCSは共有ロックを取得し、インスタンスAに対して要求されたブロックをインスタンスBへ送るよう指示します。
Read-Writeシナリオ
こちらはクリティカルなシナリオです。
インスタンスAがデータブロックを更新中のため、排他ロックを取得しています。しばらくして、インスタンスBが同じデータブロックに対する読み取り要求をGCSに送信します。
GCSが確認すると、インスタンスAが同じブロックに対して排他ロックを取得済みであることがわかります。そこでGCSはインスタンスAにブロックの解放を求めます。インスタンスAは自身のバッファ・キャッシュ内にCRイメージを作成し、それをインスタンスBへ送るようGCSに通知します。
このように、GCSが関与してCRイメージを作成し、要求元インスタンスへ配送する部分こそが、キャッシュ・フュージョンが真価を発揮するポイントです。
Write-Writeシナリオ
インスタンスAとインスタンスBが、両方とも同じデータブロックへの排他ロックを取得しようとしている状況です。
インスタンスBがGCSにブロック要求を送ると、GCSは空き状況を確認し、インスタンスAがすでにロックを保持していることを検知します。そこでGCSはインスタンスAに対し、インスタンスBのためにブロックを解放するよう求めます。インスタンスAは自身の現在のブロックのPIをバッファ内に作成し、REDOエントリを記録したうえで、ブロックをインスタンスBへ送るようGCSに通知します。
その後、インスタンスBは受け取ったブロックを使用し、通常どおり変更を加えます。
CRイメージとPIの決定的な違い
最後に、PIとCRイメージの違いについて整理しましょう。
CRイメージは、Read-Writeタイプの競合を回避するために送られます。要求元インスタンスは書き込み操作を行う意図がないため、ブロックに対する排他ロックを必要としません。したがって読み取り操作であれば、ブロックのCRイメージだけで十分です。
一方、Write-Write競合の場合、要求元インスタンスもデータブロックに対する排他ロックを取得する必要があります。書き込み操作のためのロックを取得するには、CRイメージではなく実際のブロックが必要です。そのため保持側インスタンスは実際のブロックを送りますが、そのブロックがディスクに書き込まれるまではPIを保持する義務があります。
こうしておけば、万が一インスタンス障害やクラッシュが発生しても、OracleはRAC全体に分散したPIをもとにブロックを再構築できます。ブロックがディスクに書き込まれた後であれば、クラッシュ時のリカバリは不要になるため、関連するPIは破棄できます。
キャッシュ・フュージョンは、RACにおけるパフォーマンスチューニングやトラブルシューティングの基礎となる概念です。GCS/GESの役割、PIとCRの使い分け、3つのシナリオの挙動を正しく理解することで、マルチノード環境でのブロック転送や待機イベントの分析が格段にしやすくなります。
-
MongoDBのディスク使用量を理解する――領域割り当ての仕組みと最適化の判断基準
はじめにMongoDBを使い始めたばかりの方にとって、そのディスク(スペース)使用量は一見すると分かりにくいものです。本記事では、MongoDBがどのようにディスク領域を割り当てるのか、そしてObjectRocketダッシュボードに表示される使用量情報をどう読み解けばよいのかを解説します。これにより、インスタンスのコンパクション(最適化)が必要なタイミングや、シャードを追加して利用可能領域を拡張すべきタイミングを適切に判断できるようになります。検証環境:5GBシングルシャードのMediumインスタンスまず、5GBのシャード1つで構成された真っさらなMediumインスタンスを用意します。このイン
-
ビッグデータ・データマイニング・機械学習の違いとは?基礎から徹底解説
ビッグデータ・データマイニング・機械学習の違いとは?基礎から徹底解説テクノロジーは目覚ましいスピードで進化しており、私たちは複雑に絡み合うデータのネットワークへと足を踏み入れつつあります。その一方で、世界中の企業はビッグデータ、データマイニング、機械学習といった革新的なテクノロジーの導入によって、事業の大転換を図ろうとしています。では、なぜ世界中のビジネスがこれらの技術の導入に躍起になっているのでしょうか?それぞれの基本的な概念とは何か、そして互いにどのような違いがあるのかを見ていきましょう。なぜビッグデータ、データマイニング、機械学習が必要なのか?データ需要の高まりと競争の激化により、各企業