プライマリ・コンテンツに移動
Oracle® GoldenGate Oracle GoldenGateリファレンスfor Windows and UNIX
12c (12.1.2)
E49845-08
  目次へ移動
目次

前
 
次
 

HANDLECOLLISIONS | NOHANDLECOLLISIONS

適用対象

Replicat

説明

HANDLECOLLISIONSおよびNOHANDLECOLLISIONSパラメータでは、ReplicatがターゲットにSQLを適用するときに、重複レコード・エラーおよび紛失レコード・エラーの解決を試行させるかどうかを制御します。このようなエラー(コリジョン)は、Oracle GoldenGateがソース表に対して行われたトランザクション変更をレプリケートしている間に、初期ロード(ソース表のデータをターゲット表にロード)が実行される場合に発生します。初期ロードが終了してOracle GoldenGateがレプリケートされた変更を適用するとき、HANDLECOLLISIONSによって、これらのコリジョンに対するエラー処理ロジックがReplicatに提供されます。

HANDLECOLLISIONSおよびNOHANDLECOLLISIONSは、次の方法で使用できます。

  • HANDLECOLLISIONSおよびNOHANDLECOLLISIONSをグローバルに有効化するには、パラメータ・ファイルのルート・レベルに指定します。一方のパラメータは、逆の意味のパラメータが出現するまで、パラメータ・ファイル内の後続のすべてのMAP文に対して有効です。

  • 特定のMAPパラメータ内でHANDLECOLLISIONSまたはNOHANDLECOLLISIONSを有効化すると、そのソースとターゲットのマッピングについてのみエラー処理の有効と無効を切り替えることができます。

これらの方法を組み合せて使用できます。グローバルなコリジョン処理ルールを指定し、その規則をMAP文の別のコリジョン処理ルールでオーバーライドできます。MAPの指定は常にグローバル指定よりも優先されます。

HANDLECOLLISIONSの動作

次の例で、HANDLECOLLISIONSの動作を説明します。

  • Replicatが、Oracle GoldenGateがキーとして使用している列への更新を検出すると、処理は次のようになります。

    • 古いキーが含まれる行がターゲットに見つからない場合、トレイル内の変更レコードは挿入に変換されます。

    • 新しいキーが含まれる行がターゲットに存在する場合、Replicatは古いキーが含まれる行を削除し(更新が正常に実行された場合は、このような行は存在しません)、新しいキーが含まれる行は、トレイル値が現在の値を置き換える上書きとして更新されます。

    このロジックでは、デフォルトで、または強制的に(OracleデータベースのADD TRANDATACOLSオプションを使用するなど)、表内のすべての列(変更された列のみではない)をトランザクション・ログに書き込む必要があります。詳細は、「紛失した列値を回避するために考えられる解決策」を参照してください。

  • Replicatが重複レコード・エラーを検出すると、初期ロードで適用された静的レコードは、トレイル内の変更レコードによって上書きされます。操作の観点からすると、重複レコード・エラーは、無視するよりも変更を適用するほうが安全です。

  • Replicatは、キー列に影響しない更新または削除操作中に紛失レコード・エラーを検出すると、トレイル内の変更レコードを破棄します。このようなエラーは、表データが初期ロード・プロセスによって抽出される前に、ソース表でレコードが変更および削除されている場合に発生します。例:

    1. アプリケーションがソース表のレコードA1を更新します。

    2. Extractがこの更新を抽出します。

    3. アプリケーションがソース表1のレコードAを削除します。

    4. Extractがこの削除を抽出します。

    5. Oracle GoldenGateが、レコードAが存在しないソース表1から初期ロード・データを抽出します。

    6. Oracle GoldenGateがレコードAなしで初期ロードを適用します。

    7. ReplicatがレコードAの更新の適用を試みます。

    8. データベースは"レコード紛失"エラーを返します。

    9. ReplicatがレコードAの削除の適用を試みます。

    10. データベースは"レコード紛失"エラーを返します。

初期ロード中に取得されたトランザクション変更がターゲット表に適用されたら、HANDLECOLLLIONSを無効化し、その後のエラーがReplicatによって自動的に処理されないようにします。初期同期以降に発生するエラーは異常な状態を意味するため、解決方法を特定できる担当者によって検証される必要があります。たとえば、紛失エラーは、ソース表に存在するデータがターゲット・システムから誤って削除されたことが原因の可能性があります。

HANDLECOLLISIONSは、次の方法で無効化できます。

  • Replicatを停止し、Replicatパラメータ・ファイルからHANDLECOLLISIONSを削除します(ターゲットにレイテンシが生じる可能性があります)。または、パラメータ・ファイルを編集して、エラー処理を無効化するMAP文の前にNOHANDLECOLLISIONSを追加できます。

  • Replicatの実行中にGGSCIを実行し、SEND REPLICATコマンドと該当の表に対するNOHANDLECOLLISIONSオプションを使用します。詳細は、「SEND REPLICAT」を参照してください。


    注意:

    SEND REPLICATを使用する場合は、HANDLECOLLISIONSが再度有効化されないように、Replicatの実行を次に開始する前に、パラメータ・ファイルからHANDLECOLLISIONSを削除するか、NOHANDLECOLLISIONSパラメータを追加してください。

紛失した列値を回避するために考えられる解決策

データベースがデフォルトでソース表のすべての列値を記録しないと、Replicatが主キー更新を挿入に変換しようとするときにターゲット表にNOT NULL制約がある場合、エラーが発生します。次の方法で、このシナリオに対処できます。

  • Extractパラメータ・ファイルでNOCOMPRESSUPDATESパラメータを使用して、表のすべての列をトレイルに送信し、すべての列値を記録するようにデータベースを構成します。デフォルトでは、Extractは主キーおよび変更された列のみをトレイルに書き込みます。この方法は、操作が実行された時点で現在の値が書き込まれ、フェッチする必要がなくなるため、最も安全です。

  • Extractパラメータ・ファイルでFETCHOPTIONSパラメータをFETCHPKUPDATECOLSオプションとともに使用します。この構成では、Extractに、キー列がソース上で更新されたときに使用できない列をフェッチさせます。フェッチは現在の値で、特定の更新時の値であるとはかぎらないため、データ整合性の問題が発生する可能性があります。詳細情報、および失敗したフェッチを処理する追加のフェッチ・オプションは、「FETCHOPTIONS」を参照してください。

  • フェッチを回避するには、HANDLECOLLISIONS_ALLOWPKMISSINGROWCOLLISIONSとともに使用して、更新をINSERTに変換するかわりに、更新をスキップします。この構成では、特定の条件でデータ整合性の問題が発生する可能性もあります。詳細は、「キーの更新から挿入への変換の防止」を参照してください。

キーの更新から挿入への変換の防止

場合によっては、ターゲット行が存在しない場合に、キー列を更新する操作をINSERTに変換することは適切ではありません。このような場合、_ALLOWPKMISSINGROWCOLLISIONSオプションを使用して、挿入として適用するかわりに、Replicatに操作をスキップさせることができます。

次の例では、そのようなケースを示します。このシナリオでは、デフォルトのHANDLECOLLISIONSロジックを使用してOracle GoldenGateレプリケーションのインスタンス化を実行して、Replicatが更新を挿入に変換しようとしたときに列値が紛失した場合にどのような状況が発生するかを示しています。

ソース表およびターゲット表:

両方の表の名前はsampleです。

f1  f2                   f3  f4
1   10-01-2011 11:30:45  1   1
2   10-02-2011 14:15:20  2   2
3   10-03-2011 15:12:55  3   3
  • すべての列はNOT NULLです。

  • f1は主キーです。

  • f2は、レコードが変更されるたびに自動的に更新される日付フィールドです。

  • KEYCOLSは、f1およびf2をキーとして使用するようにOracle GoldenGateに指示するために、パラメータ・ファイルで使用されます。

  • f2を記録するために、ADD TRANDATAが適宜発行されました。列f1は主キーであるため、自動的に記録されます。

DMLの一連のイベント

  1. Extractを起動して、進行中のトランザクションを取得します。

  2. 次のように、表にUPDATEを実行します。

    update sample set f3=3 where f1=2;
    

    この操作では、列f2は現在の日時で自動的に更新されます。Oracle GoldenGateでは、これはキー更新とみなされます。

    現在、行は次のようになります。

    2   10-20-2011 08:01:32  3   3
    
  3. 同じ行のDELETEを実行します。

    delete sample where f1=2;
    

    現在、表には次の行が含まれています。

    f1  f2                   f3  f4
    1   10-01-2011 11:30:45  1   1
    3   10-03-2011 15:12:55  3   3
    
  4. HANDLECOLLISIONSを使用して、ターゲットへのソース・データのエクスポート/インポートを実行して、紛失した行や重複する行を処理します。

  5. レプリケートされた更新(update sample, set f3=3 where f1=2)は、Replicatによってトレイルから適用される最初の操作です。インポート/エクスポートが実行される前にソースから行が削除されたため、これは失敗します。

  6. キー列(f2の日時の列)を更新する操作を行うHANDLECOLLISIONSロジックに従って、ReplicatはUPDATEINSERTに変換します。

  7. すべての列値がトレイルで使用できる場合、新しいINSERTは成功します。さらに、レプリケートされた削除(delete sample where f1=2)によって行が再度削除されるため、行がソース上で削除されていても、不整合は発生しません。ただし、この例には2つの問題があります。

    • f1f2、および、変更されたf3の値のみが記録されます。f4の値は記録されないため、この値は挿入操作で使用されません。

    • すべての列にはNOT NULL制約があります。

f4の値が紛失したことにより、INSERTは失敗します。_ALLOWPKMISSINGROWCOLLISIONSを使用すると、Replicatは、UPDATEINSERTに変換するかわりにスキップします。これにより、行が存在しないため後続のDELETEは失敗し、そのため、ReplicatはデフォルトのHANDLECOLLISIONSロジックの一部としてDELETEレコードをスキップします。現在、データはソースのデータと一貫性があります。

_ALLOWPKMISSINGROWCOLLISIONSからのメッセージ

_ALLOWPKMISSINGROWCOLLISIONSはデータ損失のリスクを伴うため、これを使用する場合は警告が発行されます。警告は次のテキストのようになります。

Using _ALLOWPKMISSINGROWCOLLISIONS may cause data corruption under certain conditions.

キーへのUPDATEに、挿入への変換のための完全なアフター・イメージが含まれていない場合、次の警告メッセージも発行されます。

A complete after image is not available in SOURCE.x, at RBA 123, in file .\dirdat\aa000000, while inserting a row into TARGET.x due to a missing target row for a key update operation. NOCOMPRESSUPDATES or FETCHOPTIONS FETCHPKUPDATECOLS may be specified in the EXTRACT parameter file to include a complete image for key update operations.

初期ロードに関するその他の情報

Oracle GoldenGateの初期ロード方式の詳細は、Oracle GoldenGateの管理for Windows and UNIXを参照してください。

デフォルト

NOHANDLECOLLISIONS

構文

HANDLECOLLISIONS | NOHANDLECOLLISIONS [_ALLOWPKMISSINGROWCOLLISIONS]
[THREADS (threadID[, threadID][, ...][, thread_range[, thread_range][, ...])]
HANDLECOLLISIONS

コリジョン処理を有効にします。

_ALLOWPKMISSINGROWCOLLISIONS

HANDLECOLLISIONS_ALLOWPKMISSINGROWCOLLISIONSとともに使用すると、対応するターゲット行が存在しない場合に、主キーのUPDATE操作をスキップします。


注意:

スキップ操作によりデータの破損が発生することがあります。このトピックの説明を参照してください。

NOHANDLECOLLISIONS

コリジョン処理をオフにします。

THREADS (threadID[, threadID][, ...][, thread_range[, thread_range][, ...])

指定したスレッドについてHANDLECOLLISIONSを有効にします。パラメータ・ファイルのルート・レベルにあるグローバルなHANDLECOLLISIONS文で使用されると、指定のスレッドの場所にかかわらずすべてのMAP文で、HANDLECOLLISIONSがそのスレッドに対して有効になります。MAP文のHANDLECOLLISIONS句で使用されると、HANDLECOLLISIONSはそのMAP文のみで有効になります。

threadID[, threadID][, ...]

スレッドIDを指定するか、スレッドのカンマ区切りリストをthreadID, threadID, threadIDの形式で指定します。

thread_range[, thread_range][, ...]

スレッドの範囲をthreadIDlow-threadIDhighの形式で指定するか、範囲のカンマ区切りリストをthreadIDlow-threadIDhigh, threadIDlow-threadIDhighの形式で指定します。

threadID, threadID, threadIDlow-threadIDhighのように、これらの形式を組み合せて指定することもできます。

例1   

次の例では、パラメータ・ファイル内のすべてのMAP文に対してHANDLECOLLISIONSを有効にします。

HANDLECOLLISIONS
MAP hr.emp, TARGET hr.emp;
MAP hr.job_hist, TARGET hr.job_hist;
MAP hr.dep, TARGET hr.dep;
MAP hr.country, TARGET hr.country;
例2   

次の例では、パラメータ・ファイル内の一部のMAP文に対してのみHANDLECOLLISIONSを有効にし、それ以外に対しては無効にします。

HANDLECOLLISIONS
MAP hr.emp, TARGET hr.emp;
MAP hr.job_hist, TARGET hr.job_hist;
NOHANDLECOLLISIONS
MAP hr.dep, TARGET hr.dep;
MAP hr.country, TARGET hr.country;
例3   

次の例は、MAP文でのHANDLECOLLISIONSの基本的な使用方法です。

MAP dbo.tcust, TARGET dbo.tcust, HANDLECOLLISIONS;
例4   

次に、グローバルおよびMAPレベルを組み合せた使用例を示します。指定された表では、MAPレベルの指定がグローバル指定よりも優先されます。

HANDLECOLLISIONS
MAP hr.emp, TARGET hr.emp;
MAP hr.job_hist, TARGET hr.job_hist;
MAP hr.dep, TARGET hr.dep, NOHANDLECOLLISIONS;
MAP hr.country, TARGET hr.country, NOHANDLECOLLISIONS;
例5   

次の例では、最初のMAP文のデフォルトのスレッド0と、2番目のMAP文のスレッド3を除き、HANDLECOLLISIONSがすべてのMAP文に対してグローバルに有効化されます。

HANDLECOLLISIONS
MAP fin.*, TARGET fin.*;
MAP sales.*, TARGET sales.*;
MAP orders.*, TARGET orders.*;
MAP scott.cust, TARGET scott.cust, NOHANDLECOLLISIONS;
MAP amy.cust, TARGET amy.cust, THREAD(3), NOHANDLECOLLISIONS;
例6   

この例では、HANDLECOLLISIONSがグローバルに有効化されますが、スレッド3に対しては無効です。その他のスレッド1、2および4はコリジョンを処理します。

HANDLECOLLISIONS
NOHANDLECOLLISIONS THREAD(3)
MAP scott.emplyees, TARGET scott.employees, THREADRANGE(1,4, OID);
MAP scott.inventory, TARGET scott.inventory, THREADRANGE(1,4, OID);
MAP scott.cust, TARGET scott.cust, THREADRANGE(1,4, OID);
例7   

この例では、HANDLECOLLISIONSがグローバルに有効化されますが、スレッド5から7に対してはグローバルに無効化されます。HANDLECOLLISIONSパラメータでスレッドまたは範囲が指定されないため、最初のMAP文ではすべてのスレッドがコリジョンを処理します。2番目のMAP文では、スレッド4、8および9がコリジョンを処理します。グローバルのNOHANDLECOLLISIONSがスレッド5から7に適用されるためです。

HANDLECOLLISIONS
NOHANDLECOLLISIONS THREADRANGE(5-7)
MAP scott.cust, TARGET scott.cust, THREADRANGE(4,9,OID), HANDLECOLLISIONS; 
MAP scott.offices, TARGET scott.offices, THREADRANGE(4,9,OID);
MAP scott.emp, TARGET scott.emp, THREADRANGE(4,9,OID);
MAP scott.ord, TARGET scott.ord, THREADRANGE(4,9,OID);
MAP acct.*, TARGET acct.*;
MAP admin.*, TARGET admin.*;