HANDLECOLLISIONS | NOHANDLECOLLISIONS

適用対象

Replicat

説明

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

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

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

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

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

ノート:

統合Replicatのエラー処理にHANDLECOLLISIONSを指定することは適切ではありません。HANDLECOLLISIONSを使用するかわりに、正確なインスタンス化メソッドを使用することをお薦めします。

HANDLECOLLISIONSの動作

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

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

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

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

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

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

  • HANDLECOLLISIONSを使用した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. データベースは"レコード紛失"エラーを返します。

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

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

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

  • Replicatの実行中にGGSCIを実行し、SEND REPLICATコマンドと該当の表に対するNOHANDLECOLLISIONSオプションを使用します。

    ノート:

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

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

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

  • HANDLECOLLISIONSは、表にターゲット表に対するNOT NULL主キー制約またはNOT NULL一意制約が設定されていることを必要とします。

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

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

デフォルトでデータベースにすべての列が含まれている場合は、HANDLECOLLISIONSが適切に動作するように、NOCOMPRESSUPDATESNOCOMPRESSDELETESを使用する必要があります。データベースでNOCOMPRESSDELETESがサポートされていない場合は、FETCHOPTIONS MISSINGCOLSを使用する必要があります。

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

Oracle GoldenGateの初期ロード方法の詳細は、『Oracle GoldenGateの管理』を参照してください。

デフォルト

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.*;