手動の競合検出および解決

特定のパラメータを使用した競合検出および解決(CDR)の手動構成について学習します。アクティブ/アクティブ構成のOracle GoldenGateでは、同じデータセットを持つ複数のデータベース間でデータの同期性を維持する必要があるため、競合検出および解決が必要です。

Oracle GoldenGate CDR機能の概要

Oracle GoldenGateの競合検出および解決(CDR)には、競合検出および競合解決の2つの部分があります。競合解決を開始する前に、競合検出を調査して完了することが重要です。

Oracle GoldenGateの競合検出および解決(CDR)は、次の処理を行う基本的な競合解決ルーチンを備えています。

競合検出および解決(CDR)を使用するには、ターゲット・データベースがWindows、Linux、UNIXのいずれかのシステムに配置されている必要があります。これは、NonStopプラットフォーム上のデータベースに対してはサポートされません。

CDRは、次のようなスカラー・データ型をサポートしています。

つまり、これらの列タイプは、COMPARECOLSパラメータで使用でき、さらに、RESOLVECONFLICTパラメータのUSEMINおよびUSEMAXオプションの解決列として使用することができます。RESOLVECONFLICTのUSEDELTAオプションに使用できるのは、NUMERIC列のみです。USEMAX、USEMINでは、TIMESTAMPおよびNUMBERのみがサポートされます。

ReplicatがBATCHSQLモードで動作する場合、競合解決は実行されません。BATCHSQLモードで競合が発生すると、ReplicatはGROUPTRANSOPSモードに戻り、さらに単一トランザクション・モードに戻ります。競合の検出は3つのモードすべてで行われます。

競合解決のためのOracle GoldenGateパラメータ・ファイルの構成

競合検出および解決をサポートするには、次のパラメータが必要です。

  1. Replicatパラメータ・ファイル内のMAPパラメータのCOMPARECOLSオプションを使用して、ReplicatのWHERE句で変更前の値とともに使用する列を指定します。変更前の値は、更新および削除の競合を検出するために、ターゲット・データベースの現行値と比較されます。(デフォルトでは、ReplicatはWHERE句で主キーのみを使用しますが、これでは競合検出には不十分な場合があります)。

  2. MAPパラメータのRESOLVECONFLICTオプションを使用して、様々な操作や競合タイプに対する競合解決ルーチンを指定します。RESOLVECONFLICTをMAP文で複数回使用すると、競合タイプごとに異なる解決を指定できます。ただし、同じ競合タイプについてRESOLVECONFLICTを繰り返して使用することはできません。同じ競合は同じ最終結果となるように、すべてのデータベースで同一の競合解決手順を使用してください。1つの競合解決方法で、発生する可能性のあるすべての競合に対応できるわけではありません。障害のリスクを最小化するために、論理的な優先順でコールできる複数のルーチンを作成する必要がある場合があります。

ノート:表に主キーと追加の一意索引または一意キーが含まれている場合、他も考慮すべき事項があります。COMPARECOLSパラメータとRESOLVECONFLICTパラメータで自動ルーチンが指定されている場合、一貫した方法で各行を一意に識別する必要があります。一貫した方法で行を識別できない場合、競合解決時にエラーが発生します。このような状況では、主キー以外の一意キーを無効化するか、または、SQLEXEC機能を使用してスローされたエラーを処理することで競合を解決できます。

これらのパラメータの詳細は、Oracle GoldenGateパラメータおよび機能リファレンスを参照してください。これらのパラメータの詳細は、「CDRの例1: USEMAX、OVERWRITE、DISCARDによるすべての競合タイプの処理」以降の例はを参照してください。

必要な列値をExtractで使用可能にする方法

CDRを使用するには、次の列値をログに記録して、Extractがその値を証跡に書き込めるようにする必要があります。

これらのパラメータとコマンドの詳細は、Oracle GoldenGateパラメータおよび機能リファレンスを参照してください。これらのパラメータがCDRでどのように動作するかについては、「CDRの例1: USEMAX、OVERWRITE、DISCARDによるすべての競合タイプの処理」以降の例を参照してください。

CDR統計の表示

CDR機能には、競合解決の結果を表示するために次の方法が用意されています。

CDR統計の表示に使用できる様々な手法を次に示します。

レポート・ファイル

Replicatは、CDR統計をレポート・ファイルに書き込みます。

Total CDR conflicts        7
    CDR resolutions succeeded       6
    CDR resolutions failed          1
    CDR INSERTROWEXISTS conflicts   1
    CDR UPDATEROWEXISTS conflicts   4
    CDR UPDATEROWMISSING conflicts
    CDR DELETEROWEXISTS conflicts      1
    CDR DELETEROWMISSING conflicts     1

コマンドライン

CDR統計は、STATS REPLICATコマンドをREPORTCDRオプションとともに使用して、コマンドラインから表示できます。

STATS REPLICAT *group*, REPORTCDR

列変換関数

次のCDR統計を取得し、必要に応じて、例外表にマップしたり、列変換関数からの入力を受け付ける他のOracle GoldenGateパラメータで使用できます。

これらの統計を取得するには、STATSまたはDELTASTATS情報タイプを指定して@GETENV列変換関数を使用します。結果は、現在のReplicatセッションに基づいています。Replicatが停止して再起動すると、統計はリセットされます。

特定の表またはワイルドカードで指定された表のセットについて統計が返されます。

@GETENV ('STATS','TABLE','SCHEMA.TABLNAME','CDR_CONFLICTS')
@GETENV ('STATS','TABLE','SCHEMA.TABLNAME','CDR_RESOLUTIONS_SUCCEEDED')
@GETENV ('STATS','TABLE','SCHEMA.TABLNAME','CDR_RESOLUTIONS_FAILED')

Replicatパラメータ・ファイルのすべてのMAP文のすべての表について統計が返されます。

@GETENV ('STATS','CDR_CONFLICTS')
@GETENV ('STATS','CDR_RESOLUTIONS_SUCCEEDED')
@GETENV ('STATS','CDR_RESOLUTIONS_FAILED')

前述の例の'STATS'情報タイプを'DELTASTATS'に置き換えると、前回の'DELTASTATS'の実行以降の数が返されます。@GETENVの詳細は、@GETENVを参照してください。

CDRの例1: USEMAX、OVERWRITE、DISCARDによるすべての競合タイプの処理

この例では、USEMAX解決、OVERWRITE解決およびDISCARD解決を使用して、すべての競合タイプを解決します。

この例で使用する表

各例では同一のOracleデータベースを想定しています。

CREATE TABLE hr.emp_tgt(
    name varchar2(30) primary key,
    phone varchar2(10),
    address varchar2(100),
    salary number,
    balance number,
    comment varchar2(100),
    last_mod_time timestamp);

ソース・データベースでは、すべての列が補足的にログに記録されます。

ADD TRANDATA hr.emp_src, COLS (name, phone, address, salary, balance, comment, last_mod_time);

競合解決を指定したMAP文

MAP fin.src, TARGET fin.tgt,
    COMPARECOLS (ON UPDATE ALL, ON DELETE ALL),
    RESOLVECONFLICT (UPDATEROWEXISTS, (DEFAULT, USEMAX (last_mod_time)),
    RESOLVECONFLICT (INSERTROWEXISTS, (DEFAULT, USEMAX (last_mod_time)),
    RESOLVECONFLICT (DELETEROWEXISTS, (DEFAULT, OVERWRITE)),
    RESOLVECONFLICT (UPDATEROWMISSING, (DEFAULT, OVERWRITE)),
    RESOLVECONFLICT (DELETEROWMISSING, (DEFAULT, DISCARD)),
    );

MAP文の説明

次に、MAP文について説明します。

USEMAX解決によるINSERTROWEXISTSの処理

この例では、証跡とデータベースのレコードに対する適用可能な変更前イメージと変更後イメージを使用したUSEMAX解決を説明しています。ソースとターゲットに行が存在するが、一部またはすべての行の値が異なる場合の挿入解決方法を示します。

表10 USEMAX解決によるINSERTROWEXISTS競合

イメージ SQL コメント
証跡内の変更前イメージ
None (row was inserted on the source).
N/A
証跡内の変更後イメージ
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00'

last_mod_time='9/1/10 3:00は、解決列の変更後イメージです。変更後イメージが存在するため、これが解決の特定に使用されます。

ターゲット・データベース・イメージ
name='Mary' phone='111111' address='Ralston' salary=200 balance=500 comment='aaa' last_mod_time='9/1/10 1:00'
last_mod_time='9/1/10 1:00は、ターゲットの解決列の現行イメージであり、証跡内の解決列の値はこれと比較されます。
Replicatによって適用され、競合を検出する初期INSERT

SQLバインド変数:

1)'Mary' 2)'1234567890' 3)'Oracle Pkwy' 4)100 5)100 6)NULL 7)'9/1/10 3:00'
このSQLは、Maryに対する一意性競合を戻します。
競合を解決するためにReplicatによって適用されるUPDATE

SQLバインド変数:

1)'1234567890' 2)'Oracle Pkwy' 3)100 4)100 5)NULL 6)'9/1/10 3:00' 7)'Mary' 8)'9/1/10 3:00'
INSERTROWEXISTSに対してUSEMAXが指定されているため、Replicatは挿入を更新に変換し、証跡レコードのlast_mod_timeの値をデータベースの値と比較します。レコードの値の方が大きいため、証跡ファイル内の列の変更後イメージがターゲットに適用されます。

USEMAX解決によるUPDATEROWEXISTSの処理

この例では、証跡とデータベースのレコードに対する適用可能な変更前イメージと変更後イメージを使用したUSEMAX解決を説明しています。ここでは、ソースとターゲットに行が存在するが、一部またはすべての行の値が異なる場合の更新の解決方法を示します。

表11 USEMAX解決によるUPDATEROWEXISTS競合

イメージ SQL コメント
証跡内の変更前イメージ
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00'
last_mod_time='9/1/10 3:00は、解決列の変更前イメージです。
証跡内の変更後イメージ
phone='222222' address='Holly' last_mod_time='9/1/10 5:00'
last_mod_time='9/1/10 5:00は、解決列の変更後イメージです。変更後イメージが存在するため、これが解決の特定に使用されます。
ターゲット・データベース・イメージ
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=600 comment='com' last_mod_time='9/1/10 6:00'
last_mod_time='9/1/10 6:00は、ターゲットの解決列の現行イメージであり、証跡内の解決列の値はこれと比較されます。
Replicatによって適用され、競合を検出する初期UPDATE

SQLバインド変数:

1)'222222' 2)'Holly' 3)'9/1/10 5:00' 4)'Mary' 5)'1234567890' 6)'Oracle Pkwy' 7)100 8)100 9)NULL 10)'9/1/10 3:00'

balance、commentおよびlast_mod_timeの値がターゲット内で異なるため、このSQLはデータ検出されないというエラーを戻します。

COMPARECOLS文がALLに設定されているため、すべての列がWHERE句で使用されます。

競合を解決するためにReplicatによって適用されるUPDATE

SQLバインド変数:

1)'Mary' 2)'222222' 3)'Holly' 4)100 5)100 6)NULL 7)'9/1/10 5:00' 8)'Mary' 9)'9/1/10 5:00'
証跡レコードのlast_mod_timeの後の値の方がデータベース内の現行値より小さいため、データベースの値は維持されます。Replicatは、主キーと、9/1/10 5:00より小さく設定されたlast_mod_time値を含むWHEREで操作を適用します。この基準に一致する行はないため、文が失敗して「データが見つからない」というエラーが発生しますが、条件を満たさない場合はUSEMAX解決が失敗すると予想されることから、Replicatはエラーを無視します。

OVERWRITE解決によるUPDATEROWMISSING

この例では、証跡とデータベースのレコードに対する適用可能な変更前イメージと変更後イメージを使用したOVERWRITE解決を説明しています。ターゲット行が存在しない場合の解決方法を示します。論理的な解決は、行をターゲットに上書きして両方のデータベースを再度同期させることであり、この方法が使用されます。

表12 OVERWRITE解決によるUPDATEROWMISSING競合処理

イメージ SQL コメント
証跡内の変更前イメージ
name='Jane' phone='333' address='Oracle Pkwy' salary=200 balance=200 comment=NULL last_mod_time='9/1/10 7:00'
N/A
証跡内の変更後イメージ
phone='4444' address='Holly' last_mod_time='9/1/10 8:00'
 
ターゲット・データベース・イメージ
None (row for Jane is missing)
 
Replicatによって適用され、競合を検出する初期UPDATE

SQLバインド変数:

1)'4444' 2)'Holly' 3)'9/1/10 8:00' 4)'Jane' 5)'333' 6)'Oracle Pkwy' 7)200 8)200 9)NULL 10)'9/1/10 7:00'
このSQLは、データが見つからないというエラーを戻します。COMPARECOLS文がALLに設定されているため、すべての列がWHERE句で使用されます。
競合を解決するためにReplicatによって適用されるINSERT

SQLバインド変数:

1)'Jane' 2)'4444' 3)'Holly' 4)200 5)200 6)NULL 7)'9/1/10 8:00'
OVERWRITEが解決であるため、更新は挿入に変更されます。列の変更後イメージがあれば使用され、ない場合は変更前イメージが使用されます。

OVERWRITE解決によるDELETEROWEXISTSの処理

この例では、証跡とデータベースのレコードに対する適用可能な変更前イメージと変更後イメージを使用したOVERWRITE解決を説明しています。ここでは、ソース行は削除されたがターゲット行は存在する場合の解決方法を示します。この場合、OVERWRITE解決により、ターゲットに削除が適用されます。

表13 OVERWRITE解決によるDELETEROWEXISTS競合

イメージ SQL コメント
証跡内の変更前イメージ
name='Mary' phone='222222' address='Holly' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 5:00'
N/A
証跡内の変更後イメージ
None
N/A
ターゲット・データベース・イメージ
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=600 comment=com last_mod_time='9/1/10 7:00'
行はターゲットに存在しますが、phone、address、balance、comment、last_mod_timeの各列が証跡内の変更前イメージと異なっています。
Replicatによって適用され、競合を検出する初期DELETE

SQLバインド変数:

1)'Mary' 2)'222222' 3)'Holly' 4)100 5)100d 6)NULL 7)'9/1/10 5:00'

COMPARECOLS文がALLに設定されているため、すべての列がWHERE句で使用されます。

変更前の値と現行値が異なるため、データが見つからないというエラーが発生します。

競合を解決するためにReplicatによって適用されるDELETE

SQLバインド変数:

1)'Mary'
OVERWRITEが解決であるため、(整合性エラーを回避するために)主キーのみを使用してDELETEが適用されます。

DISCARD解決によるDELETEROWMISSINGの処理

この例では、証跡とデータベースのレコードに対する適用可能な変更前イメージと変更後イメージを使用したDISCARD解決を説明しています。ターゲット行が存在しない場合の解決方法を示します。ソースに対する削除の場合、ターゲット行が存在しなくてもかまわない(ターゲット行はいずれにせよ削除する必要がある)ため、解決方法は証跡内のDELETE操作を破棄することです。

表14 DISCARD解決によるDELETEROWMISSing競合

イメージ SQL コメント
証跡内の変更前イメージ
name='Jane' phone='4444' address='Holly' salary=200 balance=200 comment=NULL last_mod_time='9/1/10 8:00'
N/A
証跡内の変更後イメージ
None
N/A
ターゲット・データベース・イメージ
None (row missing)
N/A
Replicatによって適用され、競合を検出する初期DELETE

SQLバインド変数:

1)'Jane' 2)'4444' 3)'Holly' 4)200 5)200 6)NULL 7)'9/1/10 8:00'
このSQLは、データが見つからないというエラーを戻します。COMPARECOLS文がALLに設定されているため、すべての列がWHERE句で使用されます。
競合を解決するためにReplicatによって適用されるSQL
None
DELETEROWMISSINGの解決としてDISCARDが指定されているため、証跡からの削除が破棄ファイルに格納されます。

CDRの例2: USEDELTAおよびUSEMAXによるUPDATEROWEXISTSの処理

この例では、UPDATEにターゲット行は存在するが、キー以外の列が異なる場合、影響を受ける列に応じて2つの異なる解決タイプを使用してこの状況を処理し、問題を解決します。

この例で使用する表

各例では同一のOracleデータベースを想定しています。

CREATE TABLE tgt(
    name varchar2(30) primary key,
    phone varchar2(10),
    address varchar2(100),
    salary number,
    balance number,
    comment varchar2(100),
    last_mod_time timestamp);

ソース・データベースでは、すべての列が補足的にログに記録されます。

ADD TRANDATA scott.src, COLS (name, phone, address, salary, balance, comment, last_mod_time);

MAP文

MAP fin.src, TARGET fin.tgt,
    COMPARECOLS
    (ON UPDATE KEYINCLUDING (address, phone, salary, last_mod_time),
    ON DELETE KEYINCLUDING (address, phone, salary, last_mod_time)),
    RESOLVECONFLICT (
    UPDATEROWEXISTS,
    (delta_res_method, USEDELTA, COLS (salary)),
    (DEFAULT, USEMAX (last_mod_time)));

MAP文の説明

UPDATEにターゲット行は存在するが、キー以外の列が異なるUPDATEROWEXISTS競合には、列に応じて2つの異なる解決を使用します。

COMPARECOLSでは、主キー(name 列)とaddress、phone、salary、last_mod_timeの列をUPDATE操作とDELETE操作の競合検出のための比較列として使用します。(balance列とcomment列は比較されません。)

ノート: USEMAXのかわりに、USEMAXEQ解決を使用すると、>=条件を適用できます。詳細は、Oracle GoldenGateパラメータおよび機能リファレンスを参照してください

エラー処理

例外表に対するエラー処理の例は、「エラー処理のためのOracle GoldenGateパラメータ・ファイルの構成」を参照してください。

表15 USEDELTAおよびUSEMAXによるUPDATEROWEXISTS

イメージ SQL コメント
証跡内の変更前イメージ
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00'

last_mod_time='9/1/10 3:00は、USEMAX解決の解決列の変更前イメージです。

salary=100は、USEDELTA解決の変更前イメージです。

証跡内の変更後イメージ
phone='222222' address='Holly' salary=200 comment='new' last_mod_time='9/1/10 5:00'
last_mod_time='9/1/10 5:00は、USEMAXの解決列の変更後イメージです。変更後イメージが存在するため、これが解決の特定に使用されます。
ターゲット・データベース・イメージ
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=600 balance=600 comment='com' last_mod_time='9/1/10 4:00'

last_mod_time='9/1/10 4:00は、ターゲットの解決列の現行イメージであり、証跡内の解決列の値はこれと比較されます。

salary=600は、USEDELTA解決のターゲット列の現行イメージです。

Replicatによって適用され、競合を検出する初期UPDATE

SQLバインド変数:

1)'222222' 2)'Holly' 3)200 4)'new' 5)'9/1/10 5:00' 6)'Mary' 7)'1234567890' 8)'Oracle Pkwy' 9)100 10)'9/1/10 3:00'
salaryとlast_mod_timeの値が異なるため、このSQLはデータが見つからないというエラーを戻します。(commentとbalanceの値も異なりますが、これらの列は比較されません。)
USEDELTAを使用してsalaryの競合を解決するためにReplicatによって適用されるUPDATE。

SQLバインド変数:

1)200 2)100 3)'Mary'

USEDELTAでは、証跡内のsalaryの変更後イメージ(200)と証跡内のsalaryの変更前イメージ(100)の差が、ターゲットのsalaryの現行値(600)に追加されます。この場合、700になります。

600 + (200 - 100) = 700
USEMAXを使用してデフォルト列の競合を解決するためにReplicatによって適用されるUPDATE。

SQLバインド変数:

1)'222222' 2)'Holly' 3)'new' 4)'9/1/10 5:00' 5)'Mary' 6)'9/1/10 5:00'

USEMAXでは、証跡レコード内のlast_mod_timeの変更後の値がデータベースの現行値より大きいため、証跡レコードの変更後の値で行が更新されます。

salary列は、USEDELTA解決のUPDATEで解決されるため、ここでは設定していません。

CDRの例3: USEDELTA、USEMAXおよびIGNOREによるUPDATEROWEXISTSの処理

この例では、UPDATEにターゲット行は存在するが、キー以外の列は異なる場合、影響を受ける列に応じて3つの異なる解決タイプを使用してこの状況を処理し、競合を解決します。

この例で使用する表

各例では同一のOracleデータベースを想定しています。

CREATE TABLE tgt(
    name varchar2(30) primary key,
    phone varchar2(10),
    address varchar2(100),
    salary number,
    balance number,
    comment varchar2(100),
    last_mod_time timestamp);

ソース・データベースでは、すべての列が補足的にログに記録されます。

ADD TRANDATA scott.src, COLS (name, phone, address, salary, balance, comment, last_mod_time);

MAP文

MAP fin.src, TARGET fin.tgt,
    COMPARECOLS
    (ON UPDATE ALLEXCLUDING (comment)),
    RESOLVECONFLICT (
    UPDATEROWEXISTS,
    (delta_res_method, USEDELTA, COLS (salary, balance)),
    (max_res_method, USEMAX (last_mod_time), COLS (address, last_mod_time)),
    (DEFAULT, IGNORE));

MAP文の説明

エラー処理

例外表に対するエラー処理の例は、「エラー処理のためのOracle GoldenGateパラメータ・ファイルの構成」を参照してください。

表16 USEDELTA、USEMAXおよびIGNOREによるUPDATEROWEXISTSの実行

イメージ SQL コメント
証跡内の変更前イメージ
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00

last_mod_time='9/1/10 3:00は、USEMAX解決の解決列の変更前イメージです。

salary=100とbalance=100は、USEDELTA解決の変更前イメージです。

証跡内の変更後イメージ
phone='222222' address='Holly' salary=200 comment='new' last_mod_time='9/1/10 5:00'

last_mod_time='9/1/10 5:00は、USEMAXの解決列の変更後イメージです。変更後イメージが存在するため、これが解決の特定に使用されます。

salary=200は、USEDELTA解決の唯一の変更後イメージです。balanceについては、変更前イメージが計算で使用されます。

ターゲット・データベース・イメージ
name='Mary' phone='1234567890' address='Ralston' salary=600 balance=600 comment='com' last_mod_time='9/1/10 4:00'

last_mod_time='9/1/10 4:00は、USEMAXのターゲットの解決列の現行イメージであり、証跡内の解決列の値はこれと比較されます。

salary=600とbalance=600は、USEDELTAのターゲット列の現行イメージです。

Replicatによって適用され、競合を検出する初期UPDATE

SQLバインド変数:

1)'222222' 2)'Holly' 3)200 4)'new' 5)'9/1/10 5:00' 6)'Mary' 7)'1234567890' 8)'Oracle Pkwy' 9)100 10)100 11)'9/1/10 3:00'
address、salary、balance、last_mod_timeの各列の値が異なるため、このSQLはデータが見つからないというエラーを戻します。
USEDELTAを使用してsalaryの競合を解決するためにReplicatによって適用されるUPDATE。

SQLバインド変数:

1)200 2)100 3)'Mary'
salaryには100の差がありますが、balanceの値に変更がなかったため、更新のSQLではsalaryは不要です。USEDELTAでは、証跡内のsalaryの変更後イメージ(200)と変更前イメージ(100)の差が、ターゲットのsalaryの現行値(600)に追加されます。この場合、700になります。
USEMAXの競合を解決するためにReplicatによって適用されるUPDATE。

SQLバインド変数:

1)'Holly' 2)'9/1/10 5:00' 3)'Mary' 4)'9/1/10 5:00'

証跡レコード内のlast_mod_timeの変更後の値がデータベースの現行値より大きいため、その列とaddress列が証跡レコードの変更後の値で更新されます。

salary列は、USEDELTA解決のUPDATEで解決されるため、ここでは設定していません。

IGNOREに対し、Replicatによって適用されるUPDATE。

SQLバインド変数:

1)'222222' 2)'new' 3)'Mary'
DEFAULT列グループ(phoneとcomment)にIGNOREが指定されているため、解決のSQLは適用されません。

エラー処理のためのOracle GoldenGateパラメータ・ファイルの構成

手動CDRをエラー処理と併用して、解決済のエラーとCDRで解決できなかったエラーを取得する必要があります。

  1. 競合解決は、他のエラー処理パラメータ(HANDLECOLLSIONS、INSERTMISSINGUPDATESおよびREPERROR)の前に実行されます。REPERRORパラメータを使用して、CDRで解決できないエラーを処理するためのルール、またはCDRで処理しないエラーに関するルールを割り当てます。一部のエラーをREPERRORで処理し、残りをCDRで処理するのが適当なこともありますが、同じ競合を処理するようにREPERRORとCDRを構成した場合は、CDRが優先されます。INSERTMISSINGUPDATESパラメータとHANDLECOLLISIONSパラメータも、CDRで処理されない一部のエラーを処理するために使用できます。これらのパラメータについては、『Oracle GoldenGateパラメータおよび機能リファレンス』を参照してください。

  2. (オプション)例外表を作成します。例外MAP文とともに例外表を使用する場合、Replicatは競合が発生しているすべての操作を(競合が解決したかどうかにかかわらず)、例外表にマップされる例外MAP文に送信します。UPDATEとDELETEの競合をReplicatで処理する場合は、この表の主キーを省略してください。そうしないと、整合性制約エラーが発生する可能性があります。

    少なくとも、例外表にターゲット表と同じ列を含める必要があります。これらの行には、Replicatがターゲットに適用される(または適用しようとした)各行イメージが含まれます。

    さらに、追加の列を定義してその他の情報を取得し、データをトランザクションの文脈で扱うのに役立てることができます。Oracle GoldenGateには、例外MAP文を介してこの情報を取得するためのツールが用意されています。そのような列には次のものがあります(これだけに限りません)。

    • 証跡レコードの変更前イメージ。これは、col1_beforeやcol2_beforeなどの名前を持つ、ターゲット列の複製セットです。

    • ターゲット列の現行値。また、これは、col1_currentやcol2_currentなどの名前を持つ、ターゲット列の複製セットです。

    • ターゲット表の名前

    • 競合のタイムスタンプ

    • 操作タイプ

    • データベースのエラー番号

    • (オプション)データベースのエラー・メッセージ

    • 競合が解決されたかどうか

  3. 例外MAP文を作成して、例外データを例外表にマップします。例外MAP文には次の要素が含まれます。

    • (必須)INSERTALLRECORDSオプション。このパラメータを指定すると、すべての列値が例外表にマップされるように、すべてのマップ済操作がINSERTに変換されます。

    • (必須)EXCEPTIONSONLYオプション。このパラメータを指定すると、エラーを生成する操作がマップされます(成功した操作はマップされません)。

    • (オプション)COLMAP句。例外表の列の名前および定義がソース表のものと同一であり、例外表にその列のみが含まれている場合、COLMAPは不要です。ただし、名前または定義が異なる場合、あるいは例外表の追加の列があり、それらの列に追加データを移入する場合は、COLMAP句を使用してすべての列をマップします。

追加データを例外表にマップするためのツール

次に示すのは、追加列に値を移入するためにCOLMAP句で使用できるツールです。

例外MAP文のCOLMAP句でこれらの機能を組み合せて詳細な例外表にデータを移入する方法は、例外表の追加の列を含むサンプル例外マッピングを参照してください。

これらの例で示されたパラメータと列変換関数の使用方法および構文は、Oracle GoldenGateパラメータ・ファンクション・リファレンスを参照してください。

ソース列とターゲット列のみを含むサンプル例外マッピング

次のサンプル・パラメータ・ファイルは、以降のCDRの例で使用されるソース表およびターゲット表のエラー処理と単純な例外マッピングを示しています。この例でマップするのはソース列とターゲット列であり、追加の列はマップしません。次の理由から、この例の例外MAP文にはCOLMAP句は不要です。

    -- REPERROR error handling: DEFAULT represents all error types. DISCARD

    -- writes operations that could not be processed to a discard file.
REPERROR (DEFAULT, DISCARD)

    -- Specifies a discard file.
DISCARDFILE /users/ogg/discards/discards.dsc, PURGE

    -- The regular MAP statement with the CDR parameters
MAP fin.src, TARGET fin.tgt, &
COMPARECOLS (ON UPDATE ALL, ON DELETE ALL), &
RESOLVECONFLICT (UPDATEROWEXISTS, (DEFAULT, USEMAX (last_mod_time)), &
RESOLVECONFLICT (INSERTROWEXISTS, (DEFAULT, USEMAX (last_mod_time)), &
RESOLVECONFLICT (DELETEROWEXISTS, (DEFAULT, OVERWRITE)), &
RESOLVECONFLICT (UPDATEROWMISSING, (DEFAULT, OVERWRITE)), &
RESOLVECONFLICT (DELETEROWMISSING, (DEFAULT, DISCARD)), &
);

    -- Starts the exceptions MAP statement by mapping the source table to the

    -- exceptions table.
MAP fin.src, TARGET fin.exception, &

    -- directs Replicat only to map operations that caused the error specified

    -- in REPERROR.
EXCEPTIONSONLY, &

    -- directs Replicat to convert all the exceptions to inserts into the

    -- exceptions table. This is why there cannot be a primary key constraint

    -- on the exceptions table.
INSERTALLRECORDS
;

例外表の追加の列を含むサンプル例外マッピング

次のサンプル・パラメータ・ファイルは、以降のCDRの例で使用されるソース表およびターゲット表のエラー処理と複雑な例外マッピングを示しています。この例では、例外表にソース表の行と同じ行があり、コンテキスト・データを取得するための追加の列もあります。

ノート:この例では、Replicatパラメータ・ファイルに必要なその他のパラメータ(プロセス名やログイン資格証明、特定のデータベース・タイプに必要なオプションのパラメータなど)を意図的に省略し、あります。改行を使用してパラメータ文を複数の行に分割するときは、各行の末尾でアンパサンド(&)を使用します。

    -- REPERROR error handling: DEFAULT represents all error types. DISCARD
    -- writes operations that could not be processed to a discard file.
REPERROR (DEFAULT, DISCARD)
    -- Specifies the discard file.
DISCARDFILE /users/ogg/discards/discards.dsc, PURGE
    -- The regular MAP statement with the CDR parameters
MAP fin.src, TARGET fin.tgt, &
COMPARECOLS (ON UPDATE ALL, ON DELETE ALL), &
RESOLVECONFLICT (UPDATEROWEXISTS, (DEFAULT, USEMAX (last_mod_time))), &
RESOLVECONFLICT (INSERTROWEXISTS, (DEFAULT, USEMAX (last_mod_time)), &
RESOLVECONFLICT (DELETEROWEXISTS, (DEFAULT, OVERWRITE)), &
RESOLVECONFLICT (UPDATEROWMISSING, (DEFAULT, OVERWRITE)), &
RESOLVECONFLICT (DELETEROWMISSING, (DEFAULT, DISCARD))
);
    -- Starts the exceptions MAP statement by mapping the source table to the -- exceptions table.
MAP fin.src, TARGET fin.exception, &
    -- directs Replicat only to map operations that caused the error specified
    -- in REPERROR.
EXCEPTIONSONLY, &
    -- directs Replicat to convert all the exceptions to inserts into the
    -- exceptions table. This is why there cannot be a primary key constraint
    -- on the exceptions table.
INSERTALLRECORDS &
    -- SQLEXEC query to select the values from the target record before the
    -- Replicat statement is applied. These are mapped to the *_target
    -- columns later.
SQLEXEC (id qry, query 'select name, phone, address, salary, balance, & comment, last_mod_time from fin.tgt where name = :p1', PARAMS(p1 = name )), &
    -- Start of the column mapping, specifies use default column definitions.
COLMAP ( &
    -- USEDEFAULTS maps the source columns to the target exceptions columns
    -- that receive the after image that Replicat applied or tried to apply.
    -- In this case, USEDEFAULTS can be used because the names and definitions
    -- of the source and target exceptions columns are identical; otherwise
    -- the columns must be mapped explicitly in the COLMAP clause.
USEDEFAULTS, &
    -- captures the timestamp when the resolution was performed.
res_date = @DATENOW (), &
    -- captures and maps the DML operation type.
optype = @GETENV ('LASTERR', 'OPTYPE'), &
    -- captures and maps the database error number that was returned.
dberrnum = @GETENV ('LASTERR', 'DBERRNUM'), &
    -- captures and maps the database error that was returned.
dberrmsge = @GETENV ('LASTERR', 'DBERRMSG'), &
    -- captures and maps the name of the target table
tabname = @GETENV ('GGHEADER', 'TABLENAME'), &
    -- If the names and definitions of the source columns and the target
    -- exceptions columns were not identical, the columns would need to
    -- be mapped in the COLMAP clause instead of using USEDEFAULTS, as
    -- follows:
       -- name_after = name, &
       -- phone_after = phone, &
       -- address_after = address, &
       -- salary_after = salary, &
       -- balance_after = balance, &
       -- comment_after = comment, &
       -- last_mod_time_after = last_mod_time &
    -- maps the before image of each column from the trail to a column in the
    -- exceptions table.
name_before = @BEFORE (name), &
phone_before = @BEFORE (phone), &
address_before = @BEFORE (address), &
salary_before = @BEFORE (salary), &
balance_before = @BEFORE (balance), &
comment_before = @BEFORE (comment), &
last_mod_time_before = @BEFORE (last_mod_time), &
    -- maps the results of the SQLEXEC query to rows in the exceptions table
    -- to show the current image of the row in the target.
name_current = qry.name, &
phone_current = qry.phone, &
address_current = qry.address, &
salary_current = qry.salary, &
balance_current = qry.balance, &
comment_current = qry.comment, &
last_mod_time_current = qry.last_mod_time)
;

現在のルーチンがすべての状況で予定どおり動作することを確認したら、解決ルーチンのオーバーヘッドを削減するために、例外表に記録されるデータの量を減らすことができます。