この章では、Oracle Streamsレプリケーションの概念について説明します。 この章の内容は次のとおりです。
参照: Oracle Streamsの概要は、『Oracle Streams概要および管理』を参照してください。このマニュアルでは、『Oracle Streams概要および管理』で説明する概念を理解していることを想定しています。 |
レプリケーションとは、複数のデータベースのデータベース・オブジェクトおよびデータを共有するプロセスです。レプリケートされたデータベース・オブジェクトおよびデータを複数のデータベースでメンテナンスするために、あるデータベース上でデータベース・オブジェクトのいずれかが変更されると、その変更は他のデータベースと共有されます。したがって、データベース・オブジェクトおよびデータは、レプリケーション環境にあるすべてのデータベースで、同期状態が保たれます。Oracle Streamsレプリケーション環境では、変更が発生したデータベースはソース・データベース、変更が共有されるデータベースは接続先データベースと呼ばれます。
Oracle Streamsを使用する場合、DMLまたはDDL変更のレプリケーションでは、通常、次の3つの手順が実行されます。
取得プロセス、同期取得またはアプリケーションによって、1つ以上の論理変更レコード(LCR)が作成され、そのLCRがエンキューされます。LCRは、データベースの変更を記述する特定のフォーマットを持ったメッセージです。取得プロセスではREDOログから取得した変更がLCRに再フォーマットされ、同期取得では内部メカニズムによって変更がLCRに再フォーマットされます。アプリケーションではLCRを構成できます。変更がデータ操作言語(DML)操作の場合、各LCRでは、ソース・データベースの共有表に対するDML操作による行の変更がカプセル化されます。変更がデータ定義言語(DDL)操作の場合、LCRでは、ソース・データベースの共有データベース・オブジェクトに対するDDL変更がカプセル化されます。
伝播によって、ステージングされたLCRが別のキューに伝播されます。このキューは、通常、LCRが取得されたデータベースとは別のデータベースに存在します。LCRは、接続先データベースに到達する前に、多数のキューに伝播できます。
接続先データベースでは、適用プロセスによって、LCRが共有データベース・オブジェクトに適用され、変更がコンシュームされます。適用プロセスは、LCRをデキューして直接適用するか、またはLCRをデキューして適用ハンドラに送信できます。Oracle Streamsレプリケーション環境では、適用ハンドラは、カスタマイズされたLCRの処理を実行してから、LCRを共有データベース・オブジェクトに適用します。
手順1および手順3は必須ですが、手順2はオプションです。これは、アプリケーションによっては、LCRを接続先データベースに直接エンキューする場合があるためです。さらに、Oracle DatabaseがOracle以外のデータベースと情報を共有している異機種間レプリケーション環境では、LCRを伝播せずに、適用プロセスがOracle以外のデータベースに直接変更を適用できます。
図1-1に、Oracle Streamsレプリケーション環境での情報の流れを示します。
このマニュアルでは、レプリケーションにOracle Streamsを使用する方法について説明します。また、次の情報も含まれます。
Oracle Streamsレプリケーションに関する概念
Oracle Streamsレプリケーション環境の構成
Oracle Streamsレプリケーション環境の管理、監視およびトラブルシューティングの手順
Oracle Streamsレプリケーション環境例を作成およびメンテナンスするデモ・スクリプト
レプリケーションは、情報共有形式の1つです。Oracle Streamsではレプリケーションが実行可能になり、また、メッセージ、イベントの管理と通知、データ・ウェアハウスのロード、データ保護など、他の情報共有形式も使用できます。
参照: Oracle Streamsの他の情報共有機能の詳細は、『Oracle Streams概要および管理』を参照してください。 |
ルールとは、イベントの発生時に条件が満たされている場合に、クライアントでアクションを実行できるようにするデータベース・オブジェクトです。ルールは、Oracleの組込み部分であるルール・エンジンによって評価されます。ルールを使用して、Oracle Streamsレプリケーション環境での情報の流れを制御します。次の各メカニズムはルール・エンジンのクライアントです。
取得プロセス
同期取得
伝播
適用プロセス
ルールを使用して、これらの各Oracle Streamsクライアントの動作を制御します。ルール・セットは複数のルールで構成されています。取得プロセス、伝播および適用プロセスにはポジティブ・ルール・セットおよびネガティブ・ルール・セットを関連付けることができますが、同期取得で使用できるのはポジティブ・ルール・セットのみです。
レプリケーション環境では、Oracle Streamsクライアントは、LCRがルール・セットを満たす場合に操作を実行します。一般的に、LCRについてTRUE
と評価されるルールがネガティブ・ルール・セットに存在せず、LCRについてTRUE
と評価されるルールがポジティブ・ルール・セットに1つでも存在する場合に、変更はOracle Streamsクライアントのルール・セットを満たします。Oracle Streamsクライアントがポジティブ・ルール・セットおよびネガティブ・ルール・セットの両方に関連付けられている場合、常にネガティブ・ルール・セットが先に評価されます。
具体的には、Oracle Streamsレプリケーション環境では、次の方法で情報の流れを制御します。
取得プロセスでREDOログから取得または廃棄する変更を指定します。REDOログで検出された変更が取得プロセスのルール・セットを満たす場合、取得プロセスはその変更を取得します。REDOログで検出された変更が取得プロセスのルール・セットを満たさない場合、取得プロセスはその変更を廃棄します。
同期取得で取得または廃棄する変更を指定します。表に対するDML変更が同期取得のルール・セットを満たす場合、同期取得はその変更を取得します。表に対するDML変更が同期取得のルール・セットを満たさない場合、同期取得はその変更を廃棄します。
伝播であるキューから別のキューに伝播させるか、または廃棄するLCRを指定します。キュー内のLCRが伝播のルール・セットを満たす場合、伝播はそのLCRを伝播します。キュー内のLCRが伝播のルール・セットを満たさない場合、伝播はそのLCRを廃棄します。
適用プロセスでデキューするか、または廃棄するLCRを指定します。キュー内のLCRが適用プロセスのルール・セットを満たす場合、適用プロセスはLCRを取得および処理します。キュー内のLCRが適用プロセスのルール・セットを満たさない場合、適用プロセスはそのLCRを廃棄します。
Oracleが提供するDBMS_STREAMS_ADM
のPL/SQLパッケージを使用して、Oracle Streamsレプリケーション環境のルールを作成できます。このシステム作成ルールは、次のレベルで指定できます。
表 - 特定の表に対する変更についてTRUE
と評価されるルール条件を含みます。
スキーマ - 特定のスキーマに対する変更についてTRUE
と評価されるルール条件を含みます。
グローバル - データベースに対するすべての変更についてTRUE
と評価されるルール条件を含みます。
また、1つのシステム作成ルールがDML変更またはDDL変更のどちらかについてTRUE
と評価される場合はありますが、両方がそのように評価されることはありません。そのため、たとえば、特定の表に対するDML変更とDDL変更の両方をレプリケートする場合は、その表に対する表レベルのDMLルールおよび表レベルのDDLルールの両方が必要です。
注意: 同期取得では表ルールのみが使用されます。スキーマ・ルールおよびグローバル・ルールは無視されます。 |
参照: Oracle Streamsでルールを使用する方法の詳細は、『Oracle Streams概要および管理』を参照してください。 |
Oracle Streamsレプリケーションでは、複数データベースで異なるデータベース・オブジェクトの共有がサポートされます。Oracle Streams環境では、異なるデータベースに、異なる構造を持つ共有データベース・オブジェクトを含めることができます。LCRに必要な変更を接続先データベースで適用できるように、取得、伝播または適用中のルールベースの変換を構成できます。Oracle Streamsレプリケーションでは、ルールベースの変換は、ポジティブ・ルール・セットのルールがTRUE
と評価される場合に発生する、LCRに対する変更です。
たとえば、ソース・データベースの表は、接続先データベースの表と同じデータを持っていても、一部の列名が異なる場合があります。この場合、ルールベースの変換によって、接続先データベースで正常に適用されるように、ソース・データベースからのLCRにある列名を変更できます。
ルールベースの変換には、宣言とカスタムの2つのタイプがあります。宣言ルールベースの変換では、スキーマ名の変更、表名の変更、列の追加、列名の変更、列の削除などの行LCRの一般的な変換を実行できます。このような変換は、DBMS_STREAMS_ADM
パッケージのプロシージャを使用して指定(宣言)します。Oracle Streamsでは、PL/SQLを起動せずに内部的に宣言変換が実行されます。
カスタム・ルールベースの変換では、変換を実行するユーザー定義PL/SQLファンクションが必要です。Oracle Streamsでは、変換を実行するPL/SQLファンクションが起動されます。カスタム・ルールベースの変換を実行すると、取得LCR、永続LCRまたはユーザー・メッセージを変更できます。たとえば、カスタム・ルールベースの変換で、LCR内にある特定の列のデータ型を変更できます。カスタム・ルールベースの変換は、入力としてANYDATA
オブジェクトを取り、ANYDATA
オブジェクトを戻すPL/SQLファンクションとして定義する必要があります。
ルールベースの変換は、Oracle Streamsの情報の流れの中で、どの時点でも実行できます。取得プロセスまたは同期取得は、ポジティブ・ルール・セットのルールが変更についてTRUE
と評価される場合に、この変更についてルールベースの変換を実行できます。同様に、伝播または適用プロセスは、ポジティブ・ルール・セットのルールがメッセージについてTRUE
と評価される場合に、このメッセージについて、ルールベースの変換を実行できます。
注意: このマニュアルでは、「ルールベースの変換」という用語は、本文が宣言ルールベースの変換とカスタム・ルールベースの変換の両方に該当する場合に使用されます。このマニュアルでは、必要に応じて、2つのタイプのルールベースの変換を区別しています。 |
参照: ルールベースの変換の詳細は、『Oracle Streams概要および管理』を参照してください。 |
Oracle Streamsでは、サブセット・ルールを使用した表データのサブセット化もサポートされています。Oracle Streamsレプリケーション環境でデータベースの共有表にデータのサブセットのみが含まれている場合、データの適切なサブセットのみがサブセット表と共有されるように、Oracle Streamsを構成して表に対する変更を管理できます。たとえば、あるデータベースは、特定の部門についてのみ従業員のデータをメンテナンスできます。この場合、サブセット・ルールを使用して、その部門の従業員データの変更をサブセット表と共有できますが、他部門の従業員の変更は共有できません。
サブセット化は、Oracle Streamsの情報の流れの中で、どの時点でも実行することができます。取得プロセスまたは同期取得では、サブセット・ルールを使用して特定の表に対する変更のサブセットを取得できます。伝播では、サブセット・ルールを使用して特定の表に対する変更のサブセットを伝播できます。適用プロセスでは、サブセット・ルールを使用して特定の表に対する変更のサブセットのみを適用できます。
参照: サブセット・ルールの詳細は、『Oracle Streams概要および管理』を参照してください。 |
レプリケートされたデータベース・オブジェクトおよびデータをメンテナンスするには、データベース・オブジェクトおよびデータに対する変更を取得する必要があります。次に、この変更をレプリケーション環境内のデータベースと共有する必要があります。Oracle Streamsレプリケーション環境では、次の方法を使用して変更を取得できます。
この項では、取得プロセスの概要と、レプリケーション環境での取得プロセスに重要な概念について説明します。
参照: 取得プロセスの一般的な概念は、『Oracle Streams概要および管理』を参照してください。 |
Oracle Database内でデータベース・オブジェクトに対して行われた変更は、ユーザー・エラーやメディア障害が発生した場合にもリカバリを保証するために、REDOログに記録されます。取得プロセスはOracleバックグラウンド・プロセスであり、データベースのREDOログを読み込んで、データベース・オブジェクトに対するDMLとDDLの変更を取得します。取得プロセスで変更が取得されるソース・データベースは、常にREDOログで変更が生成されたデータベースです。取得プロセスは、これらの変更をLCRと呼ばれるメッセージ形式でフォーマットし、キューのバッファ・キュー部分にエンキューします。取得プロセスによってエンキューされたLCRは取得LCRと呼ばれます。取得プロセスを実行すると、そのルールに基づいて自動的に変更が取得されるため、取得プロセスを使用する変更の取得は、暗黙的取得の形式になります。
LCRには2種類あり、行LCRには、DML操作によって生じる表内の行に対する変更の情報が含まれ、DDL LCRには、データベース・オブジェクトに対するDDL変更の情報が含まれます。どの変更を取得するかは、ルールを使用して指定します。1つのDML操作によって、表内の複数の行が変更される場合もあります。そのため、1つのDML操作の結果が複数の行LCRになり、1つのトランザクションが複数のDML操作で構成される場合もあります。
変更は、取得ユーザーによって取得されます。取得ユーザーは、取得プロセスのルール・セットを満たすすべてのDML変更およびDDL変更を取得します。
取得プロセスでは、ソース・データベースでローカルに変更を取得するか、またはダウンストリーム・データベースでリモートに変更を取得することが可能です。図1-2に、ローカルの取得プロセスを示します。
ダウンストリーム取得とは、ソース・データベース以外のデータベース上で取得プロセスが実行されることを意味します。次のタイプのダウンストリーム取得プロセスを構成できます。
リアルタイム・ダウンストリームの取得構成: この構成では、転送サービスでソース・データベースのログ・ライター・プロセス(LGWR)を使用して、オンラインREDOログからダウンストリーム・データベースにREDOデータが送信されます。ダウンストリーム・データベースで、リモート・ファイル・サーバー・プロセス(RFS)がそのREDOデータを受信し、スタンバイREDOログに格納します。スタンバイREDOログのREDOデータは、ダウンストリーム・データベースのアーカイバによってアーカイブされます。リアルタイム・ダウンストリーム取得プロセスは、可能なかぎりスタンバイREDOログからの変更を取得し、必要に応じてアーカイブ・スタンバイREDOログからの変更を取得します。
アーカイブ・ログ・ダウンストリーム取得構成: この構成では、ソース・データベースのアーカイブREDOログ・ファイルがダウンストリーム・データベースにコピーされ、取得プロセスがこれらのアーカイブREDOログ・ファイル内の変更を取得します。ダウンストリーム・データベースにアーカイブREDOログ・ファイルをコピーするには、REDO転送サービス、DBMS_FILE_TRANSFER
パッケージ、ファイル転送プロトコル(FTP)などのメカニズムを使用します。
図1-3に、リアルタイム・ダウンストリームの取得プロセスを示します。
図1-4に、アーカイブ・ログ・ダウンストリームの取得プロセスを示します。
ローカルの取得プロセスは、可能な場合はオンラインREDOログを読み込み、それ以外の場合はアーカイブREDOログ・ファイルを読み込みます。リアルタイム・ダウンストリームの取得プロセスは、可能な場合はスタンバイREDOログを読み込み、それ以外の場合はアーカイブ・スタンバイREDOログ・ファイルを読み込みます。アーカイブ・ログ・ダウンストリームの取得プロセスは、常にアーカイブREDOログ・ファイルをソース・データベースから読み込みます。
注意:
|
サプリメンタル・ロギングでは、操作が実行されるたびにREDOログに列データが追加されます。取得プロセスは、この追加情報を取得してLCRに含めます。サプリメンタル・ロギングは、ソース・データベースに対する変更を取得する取得プロセスの場所に関係なく、常にソース・データベースで構成されます。
サプリメンタル・ロギングには、データベース・サプリメンタル・ロギングと表サプリメンタル・ロギングの2種類があります。データベース・サプリメンタル・ロギングではデータベース全体のサプリメンタル・ロギングが指定されますが、表サプリメンタル・ロギングでは、特定の表のサプリメンタル・ロギングに使用するログ・グループを指定できます。表サプリメンタル・ロギングを使用する場合は、無条件ログ・グループと条件付きログ・グループのどちらかを選択できます。
無条件ログ・グループでは、表が変更されると、指定した列が変更の影響を受けるかどうかに関係なく、その列のビフォア・イメージがログに記録されます。無条件ログ・グループは、「常時ログ・グループ」と呼ばれることがあります。条件付きログ・グループでは、ログ・グループ内の少なくとも1列が変更される場合にのみ、指定したすべての列のビフォア・イメージがログに記録されます。
データベース・レベルのサプリメンタル・ロギング、表レベルの無条件ログ・グループおよび表レベルの条件付きログ・グループによって、変更ログに記録する古い値が決定されます。
取得プロセスによって取得されたLCRを、1つ以上の適用プロセスを使用して適用する予定の場合は、接続先データベースの表内にある次のタイプの列について、ソース・データベースでサプリメンタル・ロギングを使用可能にする必要があります。
接続先データベースで変更が適用される表の主キーに使用されるソース・データベースの列はすべて、ログ・グループに無条件でログを記録するか、主キー列のデータベース・サプリメンタル・ロギングによってログを記録する必要があります。
変更を適用する適用プロセスの並列性が2以上の場合、ソース・データベースの複数の列に基づく接続先データベースの一意制約列は、条件付きでログに記録する必要があります。一意制約列がソース・データベースの1つの列に基づく場合は、サプリメンタル・ロギングを指定する必要はありません。
変更を適用する適用プロセスの並列性が2以上の場合、ソース・データベースの複数の列に基づく接続先データベースの外部キー列は、条件付きでログに記録する必要があります。外部キー列がソース・データベースの1つの列に基づく場合は、サプリメンタル・ロギングを指定する必要はありません。
変更を適用する適用プロセスの並列性が2以上の場合、ソース・データベースの複数の列に基づく接続先データベースのビットマップ索引列は、条件付きでログに記録する必要があります。ビットマップ索引列がソース・データベースの1つの列に基づく場合は、サプリメンタル・ロギングを指定する必要はありません。
接続先データベースで適用プロセスの代替キー列として使用されるソース・データベースの列は、無条件でログに記録する必要があります。表の代替キー列を指定するには、DBMS_APPLY_ADM
パッケージのSET_KEY_COLUMNS
プロシージャを使用します。
ソース・データベースの複数の列が接続先データベースの列リストに使用されている場合、適用時に競合解消用の列リストで指定された列は、条件付きでログに記録する必要があります。
接続先データベースのDMLハンドラまたはエラー・ハンドラで使用されるソース・データベースの列は、無条件でログに記録する必要があります。
ルールまたはルールベースの変換で使用されるソース・データベースの列は、無条件でログに記録する必要があります。
接続先データベースで値の仮想依存性定義に指定されているソース・データベースの列は、無条件でログに記録する必要があります。
接続先データベースで表の行のサブセット化を指定する場合は、宛先表に含まれるソース・データベースの列またはサブセット条件に含まれるソース・データベースの列を、無条件でログに記録する必要があります。適用プロセスの行のサブセット化条件を指定するには、DBMS_STREAMS_ADM
パッケージのADD_SUBSET_RULES
プロシージャでdml_condition
パラメータを使用します。
ソース・データベースでこれらのタイプの列にサプリメンタル・ロギングを使用しないと、これらの列が関係する変更は接続先データベースで正しく適用されない可能性があります。
注意: LOB、LONG 、LONG RAW 、ユーザー定義型およびOracleが提供する型の列は、サプリメンタル・ログ・グループに含めることはできません。 |
参照:
|
この項では、同期取得の概要と、レプリケーション環境での同期取得に重要な概念について説明します。
同期取得は、表に対するデータ操作言語(DML)変更を取得する、オプションのOracle Streamsクライアントです。同期取得では、指定した表に対するDML変更の取得に内部メカニズムが使用されます。表に対する変更を取得するように同期取得が構成されている場合、それらの表を含むデータベースはソース・データベースと呼ばれます。同期取得を実行すると、そのルールに基づいて自動的に変更が取得されるため、同期取得を使用する変更の取得は、暗黙的取得の形式になります。
表に対してDML変更を行うと、その表の1つ以上の行が変更される場合があります。同期取得は、各行の変更を取得して、行の論理変更レコード(行LCR)と呼ばれる特定のメッセージ・フォーマットに変換します。同期取得は、行LCRの取得後、行LCRを含むメッセージをキューの永続キュー部分にエンキューします。同期取得によってエンキューされるLCRは永続LCRと呼ばれます。
図1-5に、同期取得によるLCRの取得を示します。
参照:
|
カスタム・アプリケーションは、トランザクション・ログを読み込むか、トリガーを使用するか、または他のなんらかの方法で、Oracle Databaseに対する変更を取得できます。このアプリケーションではトランザクションをアセンブルし、順序付けし、それぞれの変更を論理変更レコード(LCR)に変換する必要があります。次に、アプリケーションでDBMS_STREAMS_MESSAGING
パッケージまたはDBMS_AQ
パッケージを使用して、LCRをOracle Databaseにエンキューします。アプリケーションは、各トランザクションのLCRをすべてエンキューした後にコミットする必要があります。
LCRは、ユーザーまたはアプリケーションによって手動で構成およびエンキューされるため、構成されたLCRを手動でエンキューする変更の取得は、明示的取得と呼ばれることがあります。Oracle以外のデータベースで変更を取得し、さらにその変更をOracle Databaseと共有する必要がある異機種間レプリケーション環境の場合、カスタム・アプリケーションを作成して、Oracle以外のデータベースに対して行われた変更を取得できます。
Oracle Streamsレプリケーション環境では、伝播は、レプリケートされたデータベース・オブジェクトに対する変更を共有できるように、論理変更レコード(LCR)を適切なデータベースに伝播します。ANYDATA
キューを使用してLCRをステージングし、伝播を使用して、そのLCRを適切なデータベースに伝播できます。一部の構成では、取得と適用の複合による最適化によって、取得プロセスから直接適用プロセスにLCRを送信できます。
ここでは、Oracle Streamsレプリケーション環境でのステージングと伝播について説明します。
参照: Oracle Streamsでのステージングと伝播の詳細は、『Oracle Streams概要および管理』を参照してください。 |
取得LCRは、ステージング領域にステージングされます。Oracle Streamsでのステージング領域は、他のタイプのメッセージと同様に、行LCRおよびDDL LCRを格納できるANYDATA
キューです。LCRは、次の方法でステージングされます。
取得プロセスによって取得されたLCR(取得LCR)は、バッファ・キューにステージングされます。このバッファ・キューは、キューに関連付けられたシステム・グローバル領域(SGA)メモリーです。
同期取得によって取得されたLCR(永続LCR)は、永続キューにステージングされます。この永続キューは、キューに関連付けられたハード・ディスク領域です。
アプリケーションによって取得されたLCRは、バッファ・キューまたは永続キューにエンキューできます。これらのLCRを適用プロセスによってデキューおよび処理する場合は、永続キュー(永続LCR)にエンキューする必要があります。
ステージングされたLCRには、伝播による伝播、または適用プロセスによる適用が可能になります。伝播と適用の両方が行われる場合もあります。伝播を実行すると、LCRは、伝播のルール・セットのルールに基づいて自動的に伝播されます。適用プロセスを実行すると、LCRは、適用プロセスのルール・セットのルールに基づいて自動的に適用されます。
参照: バッファ・キューの詳細は、『Oracle Streams概要および管理』を参照してください。 |
Oracle Streamsレプリケーション環境では、通常、LCRは伝播によって、ローカル・データベースのキューからリモート・データベースのキューへ伝播されます。LCRの伝播元となるキューはソース・キュー、LCRを受信するキューは宛先キューと呼ばれます。ソース・キューと宛先キューの間には、1対多、多対1または多対多の関連が可能です。
LCRが伝播によって伝播された後でも、または適用プロセスによって適用された後でも、LCRを1つ以上の他のキューに伝播するようにOracle Streamsを構成している場合は、LCRをソース・キューに残すことができます。また、ANYDATA
キューには、LCRのみでなく、LCR以外のユーザー・メッセージも格納できることに注意してください。通常、LCR以外のユーザー・メッセージは、レプリケーションではなく、メッセージ・アプリケーションで使用されます。
LCRが伝播の際、接続先データベースに到達する前に1つ以上の中間データベースを通過するように、Oracle Streamsレプリケーション環境を構成できます。このような伝播環境は有向ネットワークと呼ばれます。LCRは、中間データベースで適用プロセスによって処理される場合と、処理されない場合があります。各接続先データベースに伝播されるLCRはルールによって決定され、LCRが接続先データベースに到達するまでのルートを指定できます。
有向ネットワークを使用するメリットは、ソース・データベースと接続先データベースの間に物理的なネットワーク接続を必要としないことです。そのため、LCRをデータベース間で伝播させる必要があって、これらのデータベースを稼働させているコンピュータ同士が直接ネットワーク接続されていない場合でも、1つ以上の中間データベースによってソース・データベースと接続先データベースが接続されていれば、ネットワークを再構成せずにLCRを伝播させることができます。有向ネットワークを使用している場合に、中間サイトが長期間停止されるか、中間サイトが削除されると、ネットワークとOracle Streams環境の再構成が必要になる場合があります。
参照: 有向ネットワークの詳細は、『Oracle Streams概要および管理』を参照してください。 |
Oracle Database 11g リリース1(11.1)以上では、特定の条件下で、取得プロセスから直接適用プロセスに論理変更レコード(LCR)を送信できます。この構成は、取得と適用の複合と呼ばれます。
取得と適用の複合によって、特定の構成の取得プロセスが適用プロセスと直接通信できるように、ストリームのパスが自動的に最適化されます。 取得と適用の複合を使用している場合、取得プロセスは、データベース・リンクを介して取得プロセスから適用プロセスにLCRを直接転送する伝播送信者として機能します。 このモードでは、効率を向上させるために、バッファ・キューが最適化されます。
参照: 『Oracle Streams概要および管理』 |
Oracle Streamsレプリケーション環境では、共有データベース・オブジェクトに対する変更が取得され、適用される接続先データベースに伝播されます。各接続先データベースでこの変更を適用できるように1つ以上の適用プロセスを構成します。ここでは、Oracle Streamsレプリケーション環境での変更の適用に関する概念を説明します。
参照: 適用プロセスを使用した変更の適用の詳細は、『Oracle Streams概要および管理』を参照してください。 |
適用プロセスはオプションのOracleバックグラウンド・プロセスであり、特定のキューから論理変更レコード(LCR)とユーザー・メッセージをデキューして、それぞれを直接適用するか、ユーザー定義プロシージャにパラメータとして渡します。適用プロセスによってデキューされるLCRには、接続先データベースで適用プロセスがデータベース・オブジェクトに適用できるDML変更またはDDL変更の結果が含まれています。適用プロセスによってデキューされるユーザー定義メッセージはANYDATA
型であり、ユーザーが構成したLCRなど、どのようなユーザー・メッセージでも含めることができます。
LCRは、適用ユーザーによって適用されます。適用ユーザーは、DML操作によって生じるすべての行の変更およびすべてのDDL変更を適用します。また、適用プロセスのルールに構成されているカスタム・ルールベースの変換、および適用プロセスに構成されている適用ハンドラも実行します。
適用プロセスは、キュー内の論理変更レコード(LCR)を処理するための柔軟なメカニズムです。環境に合わせて1つ以上の適用プロセスを構成する場合に検討するオプションがあります。通常、Oracle Streams環境でレプリケーションを実行するには、適用プロセスは、LCR以外のユーザー・メッセージではなく、LCRを適用します。この項では、適用プロセスで使用可能なLCRの処理オプションについて説明します。
1つの適用プロセスでは、バッファ・キューまたは永続キューのいずれかからメッセージを適用できますが、両方を適用することはできません。接続先データベースのキューにバッファ・キューと永続キューの両方のLCRが含まれている場合、接続先データベースにはこれらのLCRをデキューする適用プロセスが2つ以上必要です。
適用プロセスでは、バッファ・キューからメッセージをデキューしている場合、取得プロセスによって取得されたメッセージ(取得LCR)のみをデキューできます。適用プロセスでは、アプリケーションによってバッファ・キューにエンキューされたメッセージはデキューできません。適用プロセスでは、永続キューからメッセージをデキューしている場合、同期取得またはアプリケーションによってエンキューされた永続LCRをデキューできます。
取得LCRをデキューする適用プロセスは、DBMS_STREAMS_ADM
パッケージまたはDBMS_APPLY_ADM
パッケージを使用して作成できますが、永続LCRをデキューする適用プロセスは、DBMS_APPLY_ADM
パッケージのCREATE_APPLY
プロシージャでのみ作成できます。
直接適用とは、適用プロセスで、ユーザー・プロシージャを実行せずにLCRが適用されることを指します。適用プロセスは、データベース・オブジェクトにLCR内の変更を正常に適用します。また、競合または適用エラーが発生した場合は、競合ハンドラまたはエラー・ハンドラと呼ばれるユーザー指定プロシージャを使用してエラーを解決しようとします。
競合ハンドラが競合を解消できる場合は、LCRが適用されるか、LCR内の変更が廃棄されます。エラー・ハンドラがエラーを解決できる場合は、必要に応じてLCRを適用する必要があります。エラー・ハンドラでは、適用前にLCRを変更することでエラーを解決できます。エラー・ハンドラがエラーを解決できない場合、適用プロセスはトランザクションとそれに関連付けられたすべてのLCRをエラー・キューに入れます。
カスタム適用とは、適用プロセスで、LCRがユーザー・プロシージャにパラメータとして渡されて処理されることを指します。ユーザー・プロシージャは、LCRをカスタマイズされた方法で処理できます。
DML文によって生じた行LCRを処理するユーザー・プロシージャはDMLハンドラと呼ばれ、DDL文によって生じたDDL LCRを処理するユーザー・プロシージャはDDLハンドラと呼ばれます。適用プロセスでは多数のDMLハンドラを使用できますが、DDLハンドラは1つのみで、適用プロセスによってデキューされるすべてのDDL LCRを処理します。
適用プロセスに関連付けられている表ごとに、行LCR内の次のタイプの各操作を処理するように個別のDMLハンドラを設定できます。
INSERT
UPDATE
DELETE
LOB_UPDATE
たとえば、hr.employees
表では、あるDMLハンドラでINSERT
操作を処理し、別のDMLハンドラでUPDATE
操作を処理することができます。
ユーザー・プロシージャは、LCRのカスタマイズされた処理に使用できます。たとえば、ある接続先データベースでhr.employees
表のDELETE
操作をスキップする場合、この表でDELETE
操作のDMLハンドラを指定すると、スキップできます。このハンドラは、表のINSERT
、UPDATE
またはLOB_UPDATE
操作では起動されません。また、DDL変更を適用前にログに記録する場合は、そのためにDDL操作を処理するユーザー・プロシージャを作成できます。
DMLハンドラでは、ユーザー・プロシージャによって設定された名前付きセーブポイントが対象の場合を除き、コミットもロールバックも行いません。DDLハンドラ内でDDLを実行するには、LCR用のEXECUTE
メンバー・プロシージャを起動します。
DMLハンドラおよびDDLハンドラの他に、適用プロセス用にプリコミット・ハンドラを指定できます。プリコミット・ハンドラは、適用プロセスによって使用されるキューで、内部コミット・ディレクティブからコミットSCNを取得するPL/SQLプロシージャです。プリコミット・ハンドラは、コミット情報をカスタマイズされた方法で処理できます。たとえば、監査表に適用プロセスのコミット情報を記録できます。
注意: DMLハンドラ、エラー・ハンドラまたはカスタム・ルールベースの変換ファンクションを使用して、LCRのLONG 、LONG RAW 、またはアセンブルされていないLOB列のデータを変更しないでください。DMLハンドラおよびエラー・ハンドラを使用すると、LOBアセンブリで構成された行LCRのLOB列を変更できます。 |
参照:
|
ここでは、適用プロセスの依存性の処理方法について説明します。
parallelism
適用プロセス・パラメータは、適用プロセスの並列性を制御します。適用プロセスの並列性が1に設定されている場合、単一の適用サーバーでは、トランザクションがソース・データベースでコミットされた順序と同じ順序で適用されます。この場合、依存性の問題は発生しません。たとえば、ソース・データベースでトランザクションAがコミットされてからトランザクションBがコミットされた場合、接続先データベースでは、トランザクションAのすべてのLCRが適用されてから、トランザクションBのLCRが適用されます。
ただし、適用プロセスの並列性が2以上の値に設定されている場合、トランザクションは、複数の適用サーバーで同時に適用されます。適用プロセスがパラレルでトランザクションを適用している場合、適用プロセスが別のトランザクションの行LCRに依存した行LCRを検出するまで、これらのトランザクションの行LCRを適用します。依存性のある行LCRが検出された場合、適用プロセスは、コミット・システム変更番号(CSCN)が小さいトランザクションのLCRの適用を終了して、このトランザクションをコミットしてから、CSCNが大きいトランザクションの残りの行LCRの適用を終了します。
たとえば、トランザクションAとトランザクションBの2つのトランザクションがあるとします。これらのトランザクションは依存トランザクションで、各トランザクションには100の行LCRが含まれます。ソース・データベースでトランザクションAがコミットされてからトランザクションBがコミットされています。したがって、2つのトランザクションのうち、トランザクションAのCSCNの方が小さいです。適用プロセスは、次の方法でこれらのトランザクションをパラレルで適用できます。
適用プロセスが、両方のトランザクションの行LCRのパラレルでの適用を開始します。
適用プロセスが、接続先データベースのデータ・ディクショナリ内の制約、または接続先データベースの仮想依存性定義を使用して、トランザクションAの行LCRとトランザクションBの行LCRの依存性を検出します。
2つのトランザクションのうち、トランザクションBのCSCNの方が大きいため、適用プロセスはトランザクションBの適用を待機し、トランザクションBの依存性のある行LCRを適用しません。トランザクションBの依存性のある行LCRより前に存在する行LCRが適用されています。たとえば、トランザクションBの依存性のある行LCRが81番目の行LCRである場合、適用プロセスは、トランザクションBの100の行LCRのうち、80の行LCRを適用しています。
2つのトランザクションのうち、トランザクションAのCSCNの方が小さいため、適用プロセスはトランザクションAのすべての行LCRを適用し、コミットします。
適用プロセスはトランザクションBの依存性のある行LCRと残りの行LCRを適用します。トランザクションBのすべての行LCRが適用されると、適用プロセスはトランザクションBをコミットします。
注意: DBMS_APPLY_ADM パッケージのSET_PARAMETER プロシージャを使用して、parallelism 適用プロセス・パラメータを設定できます。 |
適用プロセスは、次の方法で行LCRを順序付けて適用します。
1つのトランザクション内の行LCRは、常に、ソース・データベース上の対応する変更と同じ順序で適用されます。
異なるトランザクションのそれぞれの行LCRに依存した行LCRは、常に、ソース・データベース上の対応する変更と同じ順序で適用されます。適用プロセスの並列性が2以上で、適用プロセスが異なるトランザクションの行LCR間の依存性を検出する場合、常に、適用プロセスは依存性のある行LCRを実行する前にCSCNが小さいトランザクションを実行します。この動作の詳細は、「依存トランザクションが適用される方法」を参照してください。
commit_serialization
適用プロセス・パラメータがfull
に設定されている場合、適用プロセスは、依存性のある行LCRを含むかどうかにかかわらず、ソース・データベース上の対応するトランザクションと同じ順序で、すべてのトランザクションをコミットします。
commit_serialization
適用プロセス・パラメータがnone
に設定されている場合、適用プロセスは、ソース・データベース上の対応するトランザクションのコミット順序と異なる順序で、それぞれの他のトランザクションに依存しないトランザクションを適用する場合があります。
注意: DBMS_APPLY_ADM パッケージのSET_PARAMETER プロシージャを使用して、commit_serialization 適用プロセス・パラメータを設定できます。 |
共有データベース・オブジェクトの名前がソース・データベースと接続先データベースで同じであり、このオブジェクトが各データベースの同じスキーマに含まれている場合は、適用プロセスで行LCR間の依存性が自動的に検出されます。この場合、接続先データベースのデータベース・オブジェクトに制約が定義されていると想定しています。これらの制約に関する情報は、接続先データベースのデータ・ディクショナリに格納されます。
commit_serialization
パラメータの設定および適用プロセスの並列性に関係なく、常に、適用プロセスはデータベース制約によって施行されるトランザクション間の依存性を重視します。適用プロセスは、別のトランザクションの行LCRに依存する行LCRを含むトランザクションを適用する際に、行LCRを正しい順序で適用し、トランザクションを正しい順序でコミットして、依存性を保持します。適用プロセスは、取得された行LCRと永続行LCRの依存性を検出します。
ただし、アプリケーションを使用して依存性を施行する環境など、データベース制約によって依存性が施行されない環境があります。データベース制約によって施行されない共有データベース・オブジェクトに対する依存性を含む環境がある場合、これらのデータベース・オブジェクトに対する変更を適用する適用プロセスに対してcommit_serialization
パラメータをfull
に設定します。
適用プロセスで使用されるルールにルールベースの変換が指定され、その適用プロセスに適用ハンドラが構成されている場合、LCRは次の順序で処理されます。
適用プロセスが、キューからLCRをデキューします。
適用プロセスが、必要に応じて、LCRにルールベースの変換を実行します。
適用プロセスが、LCR間の依存性を検出します。
適用プロセスが、必要に応じて、適用ハンドラにLCRを渡します。
参照: 適用サーバーの詳細は、『Oracle Streams概要および管理』を参照してください。 |
適用プロセスには、パラレルで適用される行LCR間の依存性を検出するために、追加の情報が必要になる場合があります。依存性を検出するために適用プロセスに追加の情報が必要になる状況の例を次に示します。
接続先データベースのデータ・ディクショナリに、必要な情報が含まれていない。この状況の例を次に示します。
適用プロセスが、接続先データベースのデータ・ディクショナリでデータベース・オブジェクトに関する情報を検出できない。これは、ソース・データベースと接続先データベースで、データ・ディクショナリ内の共有データベース・オブジェクトの情報が異なる場合などに発生します。たとえば、ソース・データベースと接続先データベースで、共有データベース・オブジェクトの名前が異なっていたり、共有データベース・オブジェクトが異なるスキーマに含まれている場合があります。
複数の表の間に関係が存在するが、この関係が接続先データベースのデータ・ディクショナリに記録されていない。これは、パフォーマンスを向上するためにデータベース制約が定義されていない場合や、アプリケーションでのデータベースの操作時にデータベース制約でなく依存性が使用されている場合などに発生します。
依存性の計算後に、適用ハンドラによってデータが非正規化されている。たとえば、1つの行LCR内の情報を使用して、複数の表に適用される複数の行LCRが作成される場合があります。
適用プロセスが依存性を正しく判断できなかった場合、適用エラーが発生するか、不適切な処理が実行される可能性があります。前述の一部の状況では、ルールベースの変換を使用して、適用の問題を回避できます。たとえば、共有データベース・オブジェクトがソース・データベースと接続先データベースで異なるスキーマに含まれている場合、ルールベースの変換で該当するLCRのスキーマを変更できます。ただし、ルールベースの変換には、パラレル実行できないというデメリットがあります。
仮想依存性定義とは、接続先データベースでトランザクション間の依存性を検出するために、適用プロセスで使用される依存性の記述です。仮想依存性定義は、接続先データベースのデータ・ディクショナリに制約として記述されません。かわりに、DBMS_APPLY_ADM
パッケージのプロシージャを使用して指定されます。仮想依存性定義を使用すると、適用プロセスが、データ・ディクショナリ内の制約情報のみを使用した場合には検出できない依存性を検出できるようになります。依存性が検出されると、適用プロセスは、LCRおよびトランザクションを正しい順序で適用するようにスケジュールします。
仮想依存性定義によって、適用プロセスがLCRを直接適用するか、適用ハンドラにLCRを渡す前に依存性を正しく検出するために必要な情報が提供されます。仮想依存性定義を使用すると、適用ハンドラがこれらのLCRを正しく処理できるようになります。また、これらのLCRをパラレルで処理してパフォーマンスを向上できます。
仮想依存性定義では、次のいずれかのタイプの依存性を定義できます。
注意: 仮想依存性定義を指定するには、接続先データベースでOracle Database 10g リリース2(10.2)以上を実行している必要があります。 |
値依存性では、一意キーなどの表の制約または複数の表の列の関係を定義します。値依存性は、1つ以上の列に対して設定されます。適用プロセスは、値依存性を使用して、これらの列の値を含む行LCR間の依存性を検出します。値依存性では表間の仮想外部キー関係を定義できますが、外部キー関係とは異なり、値依存性では3つ以上の表の関係を定義できます。
値依存性は、表の列の関係が接続先データベースのデータ・ディクショナリに制約で記述されていない場合に役立ちます。値依存性ではこれらの関係が記述され、適用プロセスではこれらの値依存性を使用して、異なるトランザクションの複数の行LCRが接続先データベースの表の同じ列に関連していることが判別されます。パラレルで適用されるトランザクションでは、複数の行LCRが同じ列に関連する場合、これらの行LCRを含むトランザクションは依存トランザクションになります。
接続先データベースの値依存性を定義または削除するには、DBMS_APPLY_ADM
パッケージのSET_VALUE_DEPENDENCY
プロシージャを使用します。このプロシージャでは、表の列を属性として指定します。
値依存性には、次の制限が適用されます。
値依存性に指定されたデータベース・オブジェクトに関連する行LCRは、1つのソース・データベースから生成する必要があります。
それぞれの値依存性には、特定のデータベース・オブジェクトに対する1つの属性セットのみを含める必要があります。
また、接続先データベースの値依存性に指定されたすべての列に、ソース・データベースでサプリメンタル・ロギングを実行する必要があります。これらの列は、無条件でログに記録する必要があります。
オブジェクト依存性では、接続先データベースの2つのオブジェクト間の親子関係を定義します。適用プロセスは、コミット・システム変更番号(CSCN)の値が小さく、親オブジェクトを含むすべてのトランザクションのコミット後に、子オブジェクトを含むトランザクションが実行されるようにスケジュールします。適用プロセスは、各行LCR内のオブジェクト識別子を使用して依存性を検出します。適用プロセスは、オブジェクトの依存性を検出するために、各行LCR内の列の値を使用しません。
オブジェクト依存性は、表の間の関係が接続先データベースのデータ・ディクショナリに制約で記述されていない場合に役立ちます。オブジェクト依存性ではこれらの関係が記述され、適用プロセスではこれらのオブジェクト依存性を使用して、異なるトランザクションの複数の行LCRがこれらの表に関連していることが判別されます。パラレルで適用されるトランザクションでは、あるトランザクションの行LCRが子の表に関連し、別のトランザクションの行LCRが親の表に関連する場合、これらの行LCRを含むトランザクションは依存トランザクションになります。
接続先データベースでオブジェクト依存性を作成するには、CREATE_OBJECT_DEPENDENCY
プロシージャを使用します。接続先データベースでオブジェクト依存性を削除するには、DROP_OBJECT_DEPENDENCY
プロシージャを使用します。これらのプロシージャは、いずれもDBMS_APPLY_ADM
パッケージに含まれています。
注意: 適用プロセスの並列性が2以上に指定されているときに表の循環依存が存在する場合、適用プロセスのデッドロックが発生する可能性があります。循環依存の例には、表Aが表Bに対する外部キー制約を持ち、表Bが表Aに対する外部キー制約を持つ場合があります。循環依存関係にある2つの表を含む複数のトランザクションが同じSCNでコミットされると、適用プロセスのデッドロックが発生する可能性があります。 |
ここでは、表にDML変更を適用する際の考慮事項について説明します。
接続先データベースの主キー列が、更新のたびにソース・データベースのREDOログに確実に記録されるようにする必要があります。ソース・データベースの複数列のデータが含まれる接続先データベースの一意キー制約または外部キー制約には、ソース・データベースでの追加ロギングが必要です。
列をソース・データベースのログに確実に記録させるには、様々な方法があります。たとえば、列の値が更新されるたびに、その列がログに記録されます。また、Oracleには、指定した列のロギングを自動化するサプリメンタル・ロギングと呼ばれる機能があります。
ソース・データベースの単一列のデータのみが含まれる接続先データベースの一意キー制約と外部キー制約については、サプリメンタル・ロギングは不要です。ただし、ソース・データベースの複数列のデータが含まれる制約については、接続先データベースの制約で使用されるソース・データベースのすべての列が含まれる、条件付きのサプリメンタル・ログ・グループを作成する必要があります。
通常、一意キー制約と外部キー制約には、ソース・データベースおよび接続先データベースで同じ列が含まれます。ただし、適用ハンドラまたはカスタム・ルールベースの変換により、ソース・データベースの複数列制約が接続先データベースの単一キー列に結合される場合があります。また、適用ハンドラまたはカスタム・ルールベースの変換により、ソース・データベースの単一キー列が接続先データベースの複数列制約に分割される場合があります。このような場合は、ソース・データベースの制約内の列数により、条件付きのサプリメンタル・ログ・グループが必要かどうかが決定されます。ソース・データベースの制約に複数の列が存在する場合、ソース・データベースに、すべての制約列が含まれる条件付きのサプリメンタル・ログ・グループが必要です。ソース・データベースの制約に1列のみが存在する場合、キー列にサプリメンタル・ロギングは不要です。
可能な場合は、適用プロセスによって変更が適用される各表に主キーを用意する必要があります。主キーを使用できない場合は、各表に各行の一意識別子として使用できる列セットを含めることをお薦めします。Oracle Streams環境で使用する予定の表に主キーまたは一意列セットがない場合は、それに応じてこれらの表を変更することを考慮してください。
Oracleは、競合を検出してエラーを正確に処理するために、異なるデータベースで対応する行を一意に識別して一致させることができる必要があります。デフォルトでは、Oracle Streamsは、表の主キーを使用して表の各行を識別します。主キーが存在しない場合は、少なくとも1つのNOT
NULL
列を持つ最小の一意キーを使用して、表内の行を識別します。接続先データベースの表に主キーまたは少なくとも1つのNOT
NULL
列を持つ一意キーがない場合や、主キーまたは一意キー以外の列をキーとして使用する必要がある場合は、接続先データベースで代替キーを指定できます。代替キーとは、Oracleが適用中に表の各行を識別するために使用できる列または列セットです。
表の代替主キーを指定するには、DBMS_APPLY_ADM
パッケージのSET_KEY_COLUMNS
プロシージャを使用します。主キーとは異なり、代替キー列にはNULLを指定できます。また、代替キー列は、接続先データベースですべての適用プロセスについて、指定された表の既存の主キーまたは一意キーよりも優先されます。
接続先データベースで表の代替キーを指定する場合に、これらの列がソース・データベースで同じ表の主キーでなければ、ソース・データベースで代替キー列を含む無条件のサプリメンタル・ログ・グループを作成する必要があります。
代替キー列、主キー制約および一意キー制約がない場合、適用プロセスでは、LOB列、LONG
列およびLONG
RAW
列を除く表内のすべての列がキー列として使用されます。この場合、ソース・データベースでこれらの列を含む無条件のサプリメンタル・ログ・グループを作成する必要があります。行LCRでは必要な列が少ないため、表の主キー制約がない場合は代替キー列を使用することをお薦めします。
注意:
|
参照:
|
列の不一致とは、ソース・データベースの表の列と接続先データベースの同じ表の列が一致しないことです。Oracle Streams環境に列の不一致がある場合は、ルールベースの変換またはDMLハンドラを使用して、適用プロセスで適用される行LCRの列を接続先データベースにある関連表の列と一致させます。ここでは、一般的な列の不一致に対する適用プロセスの動作について説明します。
参照:
|
ソース・データベースの表にある1つ以上の列が接続先データベースの表から欠落していると、適用プロセスにエラーが発生し、エラーの原因となったトランザクションがエラー・キューに移動します。この種のエラーは、適用前にLCRから欠落している列を削除するルールベースの変換またはDMLハンドラを作成することで回避できます。特に、変換またはハンドラでは、行LCRにDELETE_COLUMN
メンバー・プロシージャを使用して、余分な列を削除できます。
接続先データベースの表の列数がソース・データベースの表よりも多い場合、適用プロセスの動作は余分な列が依存性の計算に必要かどうかに応じて異なります。余分な列が依存性の計算に使用されない場合、適用プロセスでは変更が宛先の表に適用されます。この場合、接続先データベースに余分な列に関する列のデフォルトが存在すると、すべての挿入でこれらの列にはデフォルトが使用されます。それ以外の場合、挿入されるこれらの列はNULL
になります。
ただし、余分な列が依存性の計算に使用される場合、適用プロセスではこれらの変更を含むトランザクションがエラー・キューに置かれます。依存性の計算には、次のタイプの列が必要です。
どのような変更の場合も、すべてのキー列。
INSERT
およびDELETE
文の場合は、制約に関係するすべての列。
UPDATE
文の場合、一意キー制約列や外部キー制約列などの制約列に変更がある場合は、その制約に関係するすべての列。
接続先データベースにある表の列のデータ型が、ソース・データベースにある同じ列のデータ型と一致しない場合は、列のデータ型の不一致が発生します。 列のデータ型の不一致が発生すると、適用プロセスは、特定のデータ型を自動的に変換できます。 データ型を自動的に変換できなかった場合、適用プロセスは、不一致の列に対する変更を含むトランザクションをエラー・キューに格納します。この種のエラーを回避するために、データ型を変換するカスタム・ルールベースの変換またはDMLハンドラを作成できます。
参照: 適用時の自動データ型変換の詳細は、『Oracle Streams概要および管理』を参照してください。 |
複数のデータベース間でデータが共有されるOracle Streams構成では、競合が発生する可能性があります。競合は、LCR内の古い値と、表内の予期されるデータが一致しないことです。変更の取得対象となる表とこれらの変更が適用される表について、DML変更が許可されている場合は、競合が発生する可能性があります。
たとえば、ソース・データベースのトランザクションによって行が更新されるのとほぼ同時に、それと同じ行が接続先データベースの異なるトランザクションによって更新されることがあります。この場合、2つのデータベース間でデータ整合性が重要であれば、変更が接続先データベースに伝播するときに、適用プロセスに対して、接続先データベースで変更を保持するか、ソース・データベースからの変更で置換するように指示する必要があります。データ競合が発生した場合は、競合をビジネス・ルールに従って確実に解消するメカニズムが必要です。
Oracle Streamsは競合を自動的に検出し、更新の競合の場合は、更新の競合ハンドラが構成されていれば、それを使用して解消しようとします。Oracle Streamsには様々なビルトイン・ハンドラが用意されており、ビジネス・ルールに従って競合を解消するデータベース用の競合解消システムを定義できます。ビルトイン競合解消ハンドラで解消できない固有の状況がある場合は、独自のカスタム競合解消ハンドラを作成してエラー・ハンドラまたはDMLハンドラ内で使用できます。競合検出は非キー列では無効な場合があります。
次のどのハンドラでも、行LCRを処理できます。
DMLハンドラ
エラー・ハンドラ
更新の競合ハンドラ
ここでは、これらのハンドラに関係する使用例について説明します。
DMLハンドラとエラー・ハンドラを、同じ表に対する同じ操作に同時に使用することはできません。したがって、両方のハンドラが起動される使用例はありません。
行LCRに関連ハンドラがない場合、適用プロセスは行LCRで指定された変更を直接適用しようとします。適用プロセスが行LCRを適用できる場合は、表のその行が変更されます。適用中に競合またはエラーが発生すると、エラーになった行LCRを含むトランザクションがロールバックされ、適用プロセスのルール・セットに従って適用される必要があるトランザクション内のLCRは、すべてエラー・キューに移動します。
関連する更新の競合ハンドラは構成されているが、他の関連ハンドラが構成されていない場合を考えます。適用プロセスは、行LCRで指定された変更を直接適用しようとします。適用プロセスが行LCRを適用できる場合は、表のその行が変更されます。
一意性競合や削除の競合など、更新の競合以外の条件によって適用中にエラーが発生すると、エラーになった行LCRを含むトランザクションがロールバックされ、適用プロセスのルール・セットに従って適用される必要があるトランザクション内のLCRは、すべてエラー・キューに移動します。
適用中に更新の競合が発生すると、関連する更新の競合ハンドラが起動します。更新の競合ハンドラによって競合が正常に解消されると、適用プロセスは更新の競合の解消方法に応じてLCRを適用または廃棄し、適用プロセスのルール・セットに従って適用される必要があるトランザクション内の他のLCRを引き続き適用します。更新の競合ハンドラが競合を解消できない場合は、エラーになった行LCRを含むトランザクションがロールバックされ、適用プロセスのルール・セットに従って適用される必要があるトランザクション内のLCRは、すべてエラー・キューに移動します。
適用プロセスが行LCRをDMLハンドラに渡し、関連する更新の競合ハンドラが構成されていない場合を考えます。
DMLハンドラによって行LCRが処理されます。DMLハンドラのデザイナが、この処理を全面的に制御します。一部のDMLハンドラは、SQL操作を実行するか、行LCRのEXECUTE
メンバー・プロシージャを実行する場合があります。DMLハンドラが行LCRのEXECUTE
メンバー・プロシージャを実行すると、適用プロセスは行LCRを適用しようとします。この行LCRは、DMLハンドラによって変更されている可能性があります。
DMLハンドラによって実行されるSQL操作が失敗するか、EXECUTE
メンバー・プロシージャの実行に失敗した場合、DMLハンドラは例外処理を試みることができます。DMLハンドラが例外を呼び出さなければ、適用プロセスはDMLハンドラが行LCRで適切なアクションを実行したものとみなして、適用プロセスのルール・セットに従って適用される必要があるトランザクション内の他のLCRを引き続き適用します。
DMLハンドラは、例外を処理できなければ例外を呼び出します。この場合は、エラーになった行LCRを含むトランザクションがロールバックされ、適用プロセスのルール・セットに従って適用される必要があるトランザクション内のLCRは、すべてエラー・キューに移動します。
適用プロセスが行LCRをDMLハンドラに渡し、関連する更新の競合ハンドラが構成されている場合を考えます。
DMLハンドラによって行LCRが処理されます。DMLハンドラのデザイナが、この処理を全面的に制御します。一部のDMLハンドラは、SQL操作を実行するか、行LCRのEXECUTE
メンバー・プロシージャを実行する場合があります。DMLハンドラが行LCRのEXECUTE
メンバー・プロシージャを実行すると、適用プロセスは行LCRを適用しようとします。この行LCRは、DMLハンドラによって変更されている可能性があります。
DMLハンドラによって実行されるSQL操作が失敗するか、更新の競合以外の理由でEXECUTE
メンバー・プロシージャの実行に失敗した場合の動作は、「DMLハンドラはあるが関連する更新の競合ハンドラがない場合」で説明した動作と同じです。一意性競合と削除の競合は、更新の競合ではないことに注意してください。
更新の競合が原因でEXECUTE
メンバー・プロシージャの実行に失敗した場合の動作は、このプロシージャのconflict_resolution
パラメータの設定に応じて次のように異なります。
conflict_resolution
パラメータがTRUE
に設定されている場合は、関連する更新の競合ハンドラが起動します。更新の競合ハンドラによって競合が正常に解消され、DMLハンドラによって実行された他のすべての操作が正常終了すると、DMLハンドラは例外を呼び出さずに終了し、適用プロセスはそのルール・セットに従って適用する必要があるトランザクション内の他のLCRを引き続き適用します。
更新の競合ハンドラが競合を解消できない場合、DMLハンドラは例外の処理を試みることができます。DMLハンドラが例外を呼び出さなければ、適用プロセスはDMLハンドラが行LCRで適切なアクションを実行したものとみなして、適用プロセスのルール・セットに従って適用される必要があるトランザクション内の他のLCRを引き続き適用します。DMLハンドラは、例外を処理できなければ例外を呼び出します。この場合は、エラーになった行LCRを含むトランザクションがロールバックされ、適用プロセスのルール・セットに従って適用される必要があるトランザクション内のLCRは、すべてエラー・キューに移動します。
conflict_resolution
パラメータがFALSE
に設定されている場合、関連する更新の競合ハンドラは起動しません。この場合の動作は、「DMLハンドラはあるが関連する更新の競合ハンドラがない場合」で説明した動作と同じです。
適用プロセスが行LCRを適用するときにエラーが発生した場合を考えます。このエラーは、競合または他の条件が原因となっている可能性があります。表操作用のエラー・ハンドラはありますが、関連する更新の競合ハンドラは構成されていません。
行LCRがエラー・ハンドラに渡されます。エラー・ハンドラによって行LCRが処理されます。エラー・ハンドラのデザイナが、この処理を全面的に制御します。一部のエラー・ハンドラは、SQL操作を実行するか、行LCRのEXECUTE
メンバー・プロシージャを実行する場合があります。エラー・ハンドラが行LCRのEXECUTE
メンバー・プロシージャを実行すると、適用プロセスは行LCRを適用しようとします。この行LCRは、エラー・ハンドラによって変更されている可能性があります。
エラー・ハンドラによって実行されるSQL操作が失敗するか、EXECUTE
メンバー・プロシージャの実行に失敗した場合、エラー・ハンドラは例外処理を試みることができます。エラー・ハンドラが例外を呼び出さない場合、適用プロセスは、エラー・ハンドラが行LCRで適切なアクションを実行したものとみなして、適用プロセスのルール・セットに従って適用される必要があるトランザクション内の他のLCRを引き続き適用します。
エラー・ハンドラは、例外を処理できなければ例外を呼び出します。この場合は、エラーになった行LCRを含むトランザクションがロールバックされ、適用プロセスのルール・セットに従って適用される必要があるトランザクション内のLCRは、すべてエラー・キューに移動します。
適用プロセスが行LCRを適用するときにエラーが発生した場合を考えます。表操作用のエラー・ハンドラがあり、関連する更新の競合ハンドラが構成されているとします。
エラー処理のために起動されるハンドラは、次のようにエラーのタイプに応じて異なります。
一意性競合や削除の競合など、更新の競合以外の条件によってエラーが発生すると、エラー・ハンドラが起動します。この場合の動作は、「エラー・ハンドラはあるが関連する更新の競合ハンドラがない場合」で説明した動作と同じです。
更新の競合が原因でエラーが発生すると、更新の競合ハンドラが起動します。更新の競合ハンドラによって競合が正常に解消されると、適用プロセスは、トランザクション内の適用プロセスのルール・セットに従って適用する必要がある他のLCRを引き続き適用します。この場合、エラー・ハンドラは起動されません。
更新の競合ハンドラが競合を解消できない場合は、エラー・ハンドラが起動します。エラー・ハンドラが例外を呼び出さない場合、適用プロセスは、エラー・ハンドラが行LCRで適切なアクションを実行したものとみなして、適用プロセスのルール・セットに従って適用される必要があるトランザクション内の他のLCRを引き続き適用します。エラー・ハンドラは、LCRを処理できなければ例外を呼び出します。この場合は、エラーになった行LCRを含むトランザクションがロールバックされ、適用プロセスのルール・セットに従って適用される必要があるトランザクション内のLCRは、すべてエラー・キューに移動します。
参照:
|
ここでは、表にDDL変更を適用する際の考慮事項について説明します。
ソース・データベースでDDL変更を取得して、それを接続先データベースで適用する予定の場合は、システム生成名を使用しないでください。DDL文の結果としてオブジェクト名がシステムによって生成される場合、通常、オブジェクト名はソース・データベースとそこからのDDL変更を適用する各接続先データベースで異なるものになります。オブジェクト名が異なると、将来のDDL変更に適用エラーが発生する可能性があります。
たとえば、ソース・データベースで次のDDL文を実行する場合を考えます。
CREATE TABLE sys_gen_name (n1 NUMBER NOT NULL);
この文の結果、システム生成名を持つNOT
NULL
制約が作成されます。たとえば、NOT
NULL
制約の名前がsys_001500
であるとします。この変更が接続先データベースで適用されると、この制約のシステム生成名がsys_c1000
となる場合があります。
ソース・データベースで次のDDL文を実行する場合を考えます。
ALTER TABLE sys_gen_name DROP CONSTRAINT sys_001500;
このDDL文は、ソース・データベースでは成功しますが、接続先データベースでは失敗し、適用エラーになります。
この種のエラーを回避するには、DDL文によって作成されるすべてのオブジェクトの名前を明示的に指定します。たとえば、NOT
NULL
制約の名前を明示的に指定するには、次のDDL文を実行します。
CREATE TABLE sys_gen_name (n1 NUMBER CONSTRAINT sys_gen_name_nn NOT NULL);
CREATE
TABLE
AS
SELECT
文から発生した変更を適用する場合、適用プロセスでは次の2つの手順が実行されます。
CREATE
TABLE
AS
SELECT
文が接続先データベースで実行されますが、表の構造のみが作成されます。表に行は挿入されません。CREATE
TABLE
AS
SELECT
文が失敗すると、適用プロセスがエラーになります。それ以外の場合は、文が自動コミットされ、適用プロセスによって手順2が実行されます。
適用プロセスによって、CREATE
TABLE
AS
SELECT
文の結果としてソース・データベースで挿入された行が、接続先データベースで対応する表に挿入されます。取得プロセス、伝播または適用プロセスでは、これらの挿入を伴うすべての行LCRが、それぞれのルール・セットに基づいて廃棄される場合があります。この場合、接続先データベースでは表が空のままになります。
参照: Oracle Streamsでルールを使用する方法の詳細は、『Oracle Streams概要および管理』を参照してください。 |
1つのデータベース内または複数のデータベース間で情報を共有するOracle Streams環境の場合、ソース・データベースとはREDOログ内で変更が生成されるデータベースです。次の特性を持つ環境を考えます。
取得プロセスまたは同期取得は、ソース・データベースの表に対する変更を取得し、変更をLCRとしてキューにステージングします。
適用プロセスは、同じデータベースまたはLCRが伝播された接続先データベースのどちらかで、このLCRを適用します。
このような環境では、表ごとに、ソース・データベースで特定のシステム変更番号(SCN)の後にコミットされた変更のみが適用されます。インスタンス化SCNは、各表でこの値を指定します。
インスタンス化SCNは、インスタンス化時に設定するか、またはDBMS_APPLY_ADM
パッケージのプロシージャを使用して設定できます。Oracle Streamsレプリケーション環境が構成される前に表が接続先データベースに存在しない場合、ソース・データベースからのコピーを使用して、表が物理的に作成(インスタンス化)され、インスタンス化SCNがインスタンス化時に各表に設定されます。Oracle Streamsレプリケーション環境が構成される前に表が接続先データベースにすでに存在する場合、ソース・データベースからのコピーを使用した表のインスタンス化は行われません。かわりに、DBMS_APPLY_ADM
パッケージに含まれるSET_TABLE_INSTANTIATION_SCN
、SET_SCHEMA_INSTANATIATION_SCN
またはSET_GLOBAL_INSTANTIATION_SCN
プロシージャのいずれかを使用して、表ごとに手動でインスタンス化SCNを設定する必要があります。
データベース・オブジェクトのインスタンス化SCNによって、データベース・オブジェクトに対する変更を含むLCRのうち、適用プロセスで無視されるLCRと適用されるLCRが制御されます。ソース・データベースからのデータベース・オブジェクトに関するLCRのコミットSCNが、接続先データベースでそのデータベース・オブジェクトのインスタンス化SCN以下であれば、接続先データベースの適用プロセスではLCRが廃棄されます。それ以外の場合は、適用プロセスによってLCRが適用されます。
また、接続先データベースの共有データベース・オブジェクトに複数のソース・データベースがある場合は、ソース・データベースごとにインスタンス化SCNを設定する必要があります。このインスタンス化SCNは、ソース・データベースごとに異なっていてもかまいません。エクスポート/インポートまたはトランスポータブル表領域を使用して、インスタンス化SCNを設定できます。また、DBMS_APPLY_ADM
パッケージのプロシージャを使用して、インスタンス化SCNを設定することもできます。
また、Oracle Streamsでは各データベース・オブジェクトについて非処理SCNが記録されます。非処理SCNは、その下にデータベース・オブジェクトに対する変更を適用できないSCNです。オブジェクトのインスタンス化SCNは、オブジェクトの非処理SCNの下には設定できません。この値は、オブジェクトがインスタンス化のために準備された時点でのソース・データベースのSCN値に相当します。非処理SCNは、エクスポート/インポートを使用してデータベース・オブジェクトがインスタンス化された場合にのみ、データベース・オブジェクトに設定されます。
データベース・オブジェクトのインスタンス化SCNおよび非処理SCNを表示するには、DBA_APPLY_INSTANTIATED_OBJECTS
データ・ディクショナリ・ビューを問い合せます。
適用プロセスが実行されている場合、最も古いSCNとは現在デキューおよび適用中のトランザクションの先頭SCNです。停止した適用プロセスの場合、最も古いSCNとは適用プロセスが停止した時点で適用中だったトランザクションの先頭SCNです。
最も古いSCNが重要になるのは、次の2つの一般的な使用例の場合です。
適用プロセスを実行中のデータベースを特定の時点までリカバリする必要がある場合。
適用プロセス用の変更を取得するために、既存の取得プロセスの使用を停止し、別の取得プロセスを使用する場合。
どちらの場合も、DBA_APPLY_PROGRESS
データ・ディクショナリ・ビューを問い合せて、適用プロセス用の最も古いSCNを判別する必要があります。このビューのOLDEST_MESSAGE_NUMBER
列に、最も古いSCNが含まれています。次に、適用プロセス用の変更を取得する取得プロセスの開始SCNを、最も古いSCNと同じ値に設定します。取得プロセスが他の適用プロセス用の変更を取得している場合は、取得プロセスの開始SCNをリセットすると、これらの他の適用プロセスは重複するLCRを受信することがあります。この場合、これらの適用プロセスでは重複するLCRが自動的に廃棄されます。
注意: 最も古いSCNは、取得プロセスで取得されたLCRを適用する適用プロセスに対してのみ有効です。同期取得で取得されたLCRまたは明示的にエンキューされたLCRを適用する適用プロセスには関連していません。 |
参照:
|
適用プロセスの最低水位標は、すべてのLCRが適用済となっているシステム変更番号(SCN)です。つまり、最低水位標番号以下のSCNでコミットされたLCRは確実に適用されており、それを超えるSCNでコミットされた一部のLCRも適用されている可能性があります。適用プロセスの最低水位標は、取得プロセスの適用済SCNと等価です。
適用プロセスの最高水位標は、その番号を超えて適用されたLCRのないSCNです。つまり、最高水位標を超えたSCNでコミットされたLCRは適用されていません。
1つ以上の適用プロセスについて最低水位標と最高水位標を表示するには、V$STREAMS_APPLY_COORDINATOR
およびALL_APPLY_PROGRESS
データ・ディクショナリ・ビューを問い合せます。
DBMS_DDL
パッケージのSET_TRIGGER_FIRING_PROPERTY
プロシージャを使用すると、DMLまたはDDLトリガーの起動プロパティを制御できます。このプロシージャでは、トリガーの起動プロパティを1回起動するように設定するかどうかを指定できます。
起動プロパティが1回起動するように設定されていると、次の場合にはトリガーは起動しません。
適用プロセスによって関連する変更が行われる場合。
DBMS_APPLY_ADM
パッケージのEXECUTE_ERROR
またはEXECUTE_ALL_ERRORS
プロシージャを使用して1つ以上の適用が実行エラーになったために、関連する変更が生じた場合。
トリガーは、1回起動するように設定されていなければ、前述のどちらの場合にも起動します。
デフォルトで、DMLトリガーとDDLトリガーが1回起動するように設定されます。トリガーの起動プロパティは、DBMS_DDL
パッケージのIS_TRIGGER_FIRE_ONCE
ファンクションを使用してチェックできます。
たとえば、hr
スキーマ内で、employees
表のjob_id
列またはdepartment_id
列のデータが更新されると、update_job_history
トリガーによってjob_history
表に1行が追加されます。この場合、Oracle Streams環境に次の構成が存在すると考えます。
取得プロセスまたは同期取得は、dbs1.net
データベースでこの2つの表に対する変更を取得します。
伝播は、これらの変更をdbs2.net
データベースに伝播させます。
適用プロセスは、これらの変更をdbs2.net
データベースで適用します。
どちらのデータベースでも、hr
スキーマにupdate_job_history
トリガーが存在します。
この使用例で、dbs2.net
でupdate_job_history
トリガーが1回起動するように設定されていなければ、これらのアクションの結果は次のようになります。
dbs1.net
で、employees
表の従業員に関するjob_id
列が更新されます。
dbs1.net
でupdate_job_history
トリガーが起動し、変更を記録するjob_history
表に1行が追加されます。
dbs1.net
の取得プロセスまたは同期取得は、employees
表とjob_history
表の両方に対する変更を取得します。
伝播は、これらの変更をdbs2.net
データベースに伝播させます。
dbs2.net
データベースの適用プロセスは、両方の変更を適用します。
適用プロセスによってemployees
表が更新されると、dbs2.net
でupdate_job_history
トリガーが起動します。
この場合、employees
表に対する変更は、dbs2.net
データベースで2回記録されます。1回は適用プロセスが変更をjob_history
表に適用する時点で、もう1回はupdate_job_history
トリガーが起動して、適用プロセスによってemployees
表に対して行われた変更を記録する時点です。
データベース管理者は、適用プロセスによって変更が行われるときに、dbs2.net
データベースでupdate_job_history
トリガーが起動しないようにする必要がある場合があります。同様に、データベース管理者は、適用エラー・トランザクションの実行が原因でトリガーが起動しないようにする必要がある場合もあります。update_job_history
トリガーの起動プロパティを1回起動するように設定すると、適用プロセスによって変更がemployees
表に適用されるときにも、実行されたエラー・トランザクションによってemployees
表が更新されるときにも、dbs2.net
でトリガーは起動しません。
また、ON
SCHEMA
句を使用してスキーマ・トリガーを作成した場合、スキーマにより関連する変更が実行される場合にのみ、スキーマ・トリガーが起動します。したがって、適用プロセスにより変更が適用されるとき、適用ユーザーがスキーマ・トリガーで指定されたスキーマと同じ場合にのみ起動するように設定されたスキーマ・トリガーが、常に起動します。スキーマ・トリガーが1回起動するように設定されているとき、適用ユーザーがスキーマ・トリガーで指定されたスキーマと同じかどうかにかかわらず、適用プロセスでの変更適用時にトリガーは起動しません。
たとえば、ソース・データベースおよび接続先データベースのhr
スキーマで常に起動するスキーマ・トリガーを指定した場合に、接続先データベースの適用ユーザーがstrmadmin
である場合、hr
ユーザーがソース・データベースで関連する変更を実行するときにはトリガーが起動しますが、この変更が接続先データベースで適用されるときにはトリガーは起動しません。ただし、接続先データベースのstrmadmin
スキーマで常に起動するスキーマ・トリガーを指定した場合は、ソース・データベースのトリガー仕様にかかわらず、関連する変更が適用プロセスにより適用されるときには必ずこのトリガーが起動します。
注意: 1回起動するように設定できるのは、DMLトリガーとDDLトリガーのみです。他のタイプのトリガーは、すべて常に起動します。 |
参照: SET_TRIGGER_FIRING_PROPERTY プロシージャを使用してトリガーの起動プロパティを設定する方法の詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |