この章では、Oracle GoldenGateの競合検出および解決(CDR)機能を使用する方法について説明します。アクティブ/アクティブ構成のOracle GoldenGateでは、同じデータセットを持つ複数のデータベース間でデータの同期性を維持する必要があるため、競合検出および解決が必要です。
この章の内容は次のとおりです。
Oracle GoldenGateの競合検出および解決(CDR)は、次の処理を行う基本的な競合解決ルーチンを備えています。
INSERTの一意性競合を解決します。
行は存在するが、1つ以上の列の変更前イメージがデータベースの現行値と異なる場合に発生する、UPDATEの「データが見つからない」競合を解決します。
行が存在しない場合に発生する、UPDATEの「データが見つからない」競合を解決します。
行は存在するが、1つ以上の列の変更前イメージがデータベースの現行値と異なる場合に発生する、DELETEの「データが見つからない」競合を解決します。
行が存在しない場合に発生する、DELETEの「データが見つからない」競合を解決します。
競合検出および解決(CDR)を使用するには、ターゲット・データベースがWindows、Linux、UNIXのいずれかのシステムに配置されている必要があります。これは、NonStopプラットフォーム上のデータベースに対してはサポートされません。
CDRは、明示的な変換を行わずに単純なSQLと比較することのできるデータ型をサポートしています。
NUMERIC
DATE
TIMESTAMP
CHAR/NCHAR
VARCHAR/NVARCHAR
つまり、これらの列タイプは、COMPARECOLSパラメータおよびGETBEFORECOLSパラメータで使用でき、また、RESOLVECONFLICTパラメータのUSEMINおよびUSEMAXオプションの解決列として使用できます。RESOLVECONFLICTのUSEDELTAオプションに使用できるのは、NUMERIC列のみです。CDRは、LOB、抽象データ型(ADT)またはユーザー定義型(UDT)を含む列に使用しないでください。
ReplicatがBATCHSQLモードで動作する場合、競合解決は実行されません。BATCHSQLモードで競合が発生すると、ReplicatはGROUPTRANSOPSモードに戻り、さらに単一トランザクション・モードに戻ります。競合検出は3つのモードすべてで行われます。詳細は、『Oracle GoldenGate for Windows and UNIXリファレンス』を参照してください。
ソース・データベース、ターゲット・データベースおよびOracle GoldenGateを競合検出および解決のために構成するには、次の手順を実行します。手順は次のとおりです。
CDRを使用するには、次の列値をログに記録して、Extractがその値を証跡に書き込めるようにする必要があります。
各レコードの完全な変更前イメージ。一部のデータベースは、変更前イメージをログ・レコードに記録できないため、サプリメンタル・ロギングを使用してこの処理を行うよう構成する必要があります。ほとんどのサポート対象データベースでは、ADD TRANDATAコマンドをこの目的で使用できます。
LOGALLSUPCOLSパラメータを使用して、スケジュール列の完全な変更前イメージと変更後イメージが確実に証跡に書き込まれるようにします。スケジュール列は、主キー、一意索引および外部キーの列です。LOGALLSUPCOLSを使用すると、Extractでは、UPDATE操作の変更前イメージおよびUPDATEとDELETEの両操作のサプリメンタル・ロギング列すべての変更前イメージを証跡レコードに含めるようになります。
NonStop SQL/MXソース・データベースの場合、表を作成または変更してno auditcompress属性を持たせます。
これらのパラメータとコマンドの詳細は、Oracle GoldenGateリファレンスfor Windows and UNIXを参照してください。これらのパラメータがCDRでどのように動作するかについては、10.3項「CDRの例1: USEMAX、OVERWRITE、DISCARDによるすべての競合タイプの処理」以降の例を参照してください。
競合検出および解決をサポートするには、次のパラメータが必要です。
ExtractのTABLEパラメータのGETBEFORECOLSオプションを使用して、Extractで更新操作また削除操作の変更前イメージを取得する対象列を指定します。DB2データベースの場合、DB2でサポートされないGETBEFORECOLSパラメータではなく、GETUPDATEBEFORESパラメータを使用します。
Replicatパラメータ・ファイル内のMAPパラメータのCOMPARECOLSオプションを使用して、ReplicatのWHERE句で変更前の値とともに使用する列を指定します。変更前の値は、更新および削除の競合を検出するために、ターゲット・データベースの現行値と比較されます。(デフォルトでは、ReplicatはWHERE句で主キーのみを使用しますが、これでは競合検出には不十分な場合があります)。
MAPパラメータのRESOLVECONFLICTオプションを使用して、様々な操作や競合タイプに対する競合解決ルーチンを指定します。RESOLVECONFLICTをMAP文で複数回使用すると、競合タイプごとに異なる解決を指定できます。同じ競合は同じ最終結果となるように、すべてのデータベースで同一の競合解決手順を使用してください。1つの競合解決方法で、発生する可能性のあるすべての競合に対応できるわけではありません。障害のリスクを最小化するため、状況に応じて、論理的な優先順でコールできる複数のルーチンを作成する必要があります。
|
注意: 表に主キーと他の一意索引または一意キーが含まれている場合は、他にも考慮すべき事項があります。COMPARECOLSパラメータとRESOLVECONFLICTパラメータで自動ルーチンが指定されている場合、一貫した方法で各行を一意に識別する必要があります。一貫した方法で行を識別できない場合、競合解決時にエラーが発生します。このような状況では、主キー以外の一意キーを無効化するか、または、SQLEXEC機能を使用してスローされたエラーを処理することで競合を解決できます。 |
これらのパラメータの詳細は、Oracle GoldenGateリファレンスfor Windows and UNIXを参照してください。これらのパラメータの詳細は、10.3項「CDRの例1: USEMAX、OVERWRITE、DISCARDによるすべての競合タイプの処理」以降の例を参照してください。
CDRをエラー処理と併用して、解決済のエラーとCDRで解決できなかったエラーを取得する必要があります。
競合解決は、他のエラー処理パラメータ(HANDLECOLLSIONS、INSERTMISSINGUPDATESおよびREPERROR)の前に実行されます。REPERRORパラメータを使用して、CDRで解決できないエラーを処理するためのルール、またはCDRで処理しないエラーに関するルールを割り当てます。一部のエラーをREPERRORで処理し、残りをCDRで処理するのが適当なこともありますが、同じ競合を処理するようにREPERRORとCDRを構成した場合は、CDRが優先されます。INSERTMISSINGUPDATESパラメータとHANDLECOLLISIONSパラメータも、CDRで処理されない一部のエラーを処理するために使用できます。これらのパラメータの詳細は、Oracle GoldenGateリファレンスfor Windows and UNIXを参照してください。
(オプション)例外表を作成します。例外MAP文とともに例外表を使用する場合(10.2.3項「エラー処理のためのOracle GoldenGateパラメータ・ファイルの構成」を参照)、Replicatは競合が発生しているすべての操作を(競合が解決したかどうかにかかわらず)、例外表にマップされる例外MAP文に送信します。UPDATEとDELETEの競合をReplicatで処理する場合は、この表の主キーを省略してください。そうしないと、整合性制約エラーが発生する可能性があります。
少なくとも、例外表にターゲット表と同じ列を含める必要があります。これらの行には、Replicatがターゲットに適用した(または適用しようとした)各行イメージが格納されます。
さらに、追加の列を定義してその他の情報を取得し、データをトランザクションの文脈で扱うのに役立てることができます。Oracle GoldenGateには、例外MAP文を通じてこの情報を取得するためのツールが用意されています(10.2.3項「エラー処理のためのOracle GoldenGateパラメータ・ファイルの構成」を参照)。そのような列には次のものがあります(これだけに限りません)。
証跡レコードの変更前イメージ。これは、col1_beforeやcol2_beforeなどの名前を持つ、ターゲット列の複製です。
ターゲット列の現行値。これは、col1_currentやcol2_currentなどの名前を持つ、ターゲット列の複製です。
ターゲット表の名前
競合のタイムスタンプ
操作タイプ
データベースのエラー番号
(オプション)データベースのエラー・メッセージ
競合が解決されたかどうか
例外MAP文を作成して、例外データを例外表にマップします。例外MAP文には次の要素が含まれます。
(必須)INSERTALLRECORDSオプション。このパラメータを指定すると、すべての列値が例外表にマップされるように、すべてのマップ済操作がINSERTに変換されます。
(必須)EXCEPTIONSONLYオプション。このパラメータを指定すると、エラーを生成する操作がマップされます(成功した操作はマップされません)。
(オプション)COLMAP句。例外表の列の名前および定義がソース表のものと同一であり、例外表にその列のみが含まれている場合、COLMAPは不要です。ただし、名前または定義が異なる場合、あるいは例外表に追加の列があり、それらの列に追加データを移入する場合は、COLMAP句を使用してすべての列をマップします。
次に示すのは、追加列に値を移入するためにCOLMAP句で使用できるツールです。
ソース列の名前および定義が例外表のターゲット列のものと同一である場合、明示的にマッピングを行う名前のかわりにUSEDEFAULTSキーワードを使用できます。それ以外の場合は、次の例のように、それらの列をCOLMAP句でマッピングする必要があります。
COLMAP (exceptions_col1 = col1, [...])
ソース行の変更前イメージを例外表の列にマップするには、証跡レコードから列の変更前イメージを取得する@BEFORE変換関数を使用します。次の例は、@BEFOREの使用方法を示しています。
COLMAP (USEDEFAULTS, exceptions_col1 = @BEFORE (source_col1), & exceptions_col2 = @BEFORE (source_col2), [...])
ターゲット行の現行イメージを例外表の列にマップするには、SQLEXEC問合せを使用してイメージを取得し、COLMAP句でqueryID.column構文を使用して問合せの結果を例外表の列にマップします。
COLMAP (USEDEFAULTS, name_current =queryID.name, phone_current =queryID.phone, [...])
タイムスタンプ、データベース・エラー、その他の環境情報をマップするには、該当するOracle GoldenGate列変換関数を使用します。たとえば、次の例では実行時の現行タイムスタンプをマップしています。
res_date = @DATENOW ()
例外MAP文のCOLMAP句でこれらの機能を組み合せて詳細な例外表にデータを移入する方法は、10.2.3.3項「例外表の追加の列を含むサンプル例外マッピング」を参照してください。
これらの例で示したパラメータおよび列変換関数の使用方法と構文については、Oracle GoldenGateリファレンスfor Windows and UNIXを参照してください。
次のサンプル・パラメータ・ファイルは、以降のCDRの例で使用されるソース表およびターゲット表のエラー処理と単純な例外マッピングを示しています。この例でマップするのはソース列とターゲット列であり、追加の列はマップしません。次の理由から、この例の例外MAP文にはCOLMAP句は不要です。
ソースとターゲットの例外列は、名前と定義がそれぞれ同一です。
例外表に他の列がありません。
|
注意: この例では、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 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) &
;
例外表の作成と例外マッピングの使用の詳細は、15.3項「DML操作中のReplicatエラーの処理」を参照してください。
現在のルーチンがすべての状況で予定どおり動作することを確認したら、解決ルーチンのオーバーヘッドを削減するために、例外表に記録されるデータの量を減らすことができます。
CDR機能には、競合解決の結果を表示するために次の方法が用意されています。
Replicatは、CDR統計をレポート・ファイルに書き込みます。
Total CDR conflicts 7
CDR resolutions succeeded 6
CDR resolutions failed 1
CDR INSERTROWEXISTS conflicts 1
CDR UPDATEROWEXISTS conflicts 4
CDR DELROWEXISTS conflicts 1
CDR DELROWMISSING conflicts 1
CDR統計は、STATS REPLICATコマンドをREPORTCDRオプションとともに使用して、GGSCIから表示することもできます。
STATS REPLICAT group, REPORTCDR
次のCDR統計を取得し、必要に応じて、例外表にマップしたり、列変換関数からの入力を受け付ける他のOracle GoldenGateパラメータで使用できます。
Replicatで検出した競合の数
Replicatで解決した解決の数
Replicatで解決できなかった解決の数
これらの統計を取得するには、'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の詳細は、Oracle GoldenGateリファレンスfor Windows and UNIXを参照してください。
この例では、USEMAX解決、OVERWRITE解決およびDISCARD解決を使用して、すべての競合タイプを解決します。
各例では同一の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 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文について説明します。
COMPARECOLSでは、更新および削除のReplicat WHERE句において、証跡レコード内のすべての列の変更前イメージを使用します。
DEFAULTでは、すべての競合タイプの列グループとしてすべての列を使用します。そのため、解決はすべての列に適用されます。
INSERTROWEXISTS競合には、USEMAX解決を使用します。つまり、挿入時に行が存在する場合は、last_mod_time列を解決列として使用し、証跡の値とデータベースの値のどちらが大きいかを判別します。証跡の値の方が大きい場合、レコードを適用しますが、挿入を更新に変更します。データベースの値の方が大きい場合、レコードを無視します。
UPDATEROWEXISTS競合には、USEMAX解決を使用します。つまり、更新時に行が存在する場合は、last_mod_time列を解決列として使用します。証跡の値の方が大きい場合、更新を適用します。
DELETEROWEXISTS競合には、OVERWRITE解決を使用します。つまり、削除操作時に行が存在する場合は、削除を適用します。
UPDATEROWMISSING競合には、OVERWRITE解決を使用します。つまり、更新時に行が存在しない場合は、更新を挿入に変更して適用します。
DELETROWMISSING競合には、DISCARD解決を使用します。つまり、削除操作時に行が存在しない場合は、証跡レコードを破棄します。
|
注意: USEMAXのかわりにUSEMAXEQ解決を使用すると、=条件を適用できます。詳細は、『Oracle GoldenGate for Windows and UNIXリファレンス』を参照してください。 |
この例では、証跡とデータベースのレコードに対する適用可能な変更前イメージと変更後イメージを使用したUSEMAX解決を説明しています。ソースとターゲットに行が存在するが、一部またはすべての行の値が異なる場合の挿入の解決方法を示します。
表10-1 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' |
|
|
ターゲット・データベースのイメージ |
name='Mary' phone='111111' address='Ralston' salary=200 balance=500 comment='aaa' last_mod_time='9/1/10 1:00' |
|
|
Replicatによって適用され、競合を検出する初期 |
SQLバインド変数: 1)'Mary' 2)'1234567890' 3)'Oracle Pkwy' 4)100 5)100 6)NULL 7)'9/1/10 3:00' |
このSQLは、Maryに対する一意性競合を戻します。 |
|
競合を解決するためにReplicatによって適用される |
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' |
|
この例では、証跡とデータベースのレコードに対する適用可能な変更前イメージと変更後イメージを使用したUSEMAX解決を説明しています。ソースとターゲットに行が存在するが、一部またはすべての行の値が異なる場合の更新の解決方法を示します。
表10-2 USEMAX解決によるUPDATEROWEXISTS競合の処理
| イメージ | SQL | コメント |
|---|---|---|
|
証跡内の変更前イメージ |
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=100 balance=100 comment=NULL last_mod_time='9/1/10 3:00' |
|
|
証跡内の変更後イメージ |
phone='222222' address='Holly' 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' |
|
|
Replicatによって適用され、競合を検出する初期 |
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' |
|
|
競合を解決するためにReplicatによって適用される |
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' |
証跡レコードの |
この例では、証跡とデータベースのレコードに対する適用可能な変更前イメージと変更後イメージを使用したOVERWRITE解決を説明しています。ターゲット行が存在しない場合の解決方法を示します。論理的な解決は、行をターゲットに上書きして両方のデータベースを再度同期させることであり、この方法が使用されます。
表10-3 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によって適用され、競合を検出する初期 |
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は、データが見つからないというエラーを戻します。 |
|
競合を解決するためにReplicatによって適用される |
SQLバインド変数: 1)'Jane' 2)'4444' 3)'Holly' 4)200 5)200 6)NULL 7)'9/1/10 8:00' |
|
この例では、証跡とデータベースのレコードに対する適用可能な変更前イメージと変更後イメージを使用したDISCARD解決を説明しています。ターゲット行が存在しない場合の解決方法を示します。ソースに対する削除の場合、ターゲット行が存在しなくてもかまわない(ターゲット行はいずれにせよ削除する必要がある)ため、解決方法は証跡内のDELETE操作を破棄することです。
表10-4 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によって適用され、競合を検出する初期 |
SQLバインド変数: 1)'Jane' 2)'4444' 3)'Holly' 4)200 5)200 6)NULL 7)'9/1/10 8:00' |
このSQLは、データが見つからないというエラーを戻します。 |
|
競合を解決するためにReplicatによって適用されるSQL |
None |
|
この例では、証跡とデータベースのレコードに対する適用可能な変更前イメージと変更後イメージを使用したOVERWRITE解決を説明しています。ここでは、ソース行は削除されたがターゲット行は存在する場合の解決方法を示します。この場合、OVERWRITE解決により、ターゲットに削除が適用されます。
表10-5 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' |
行はターゲットに存在しますが、 |
|
Replicatによって適用され、競合を検出する初期 |
SQLバインド変数: 1)'Mary' 2)'222222' 3)'Holly' 4)100 5)100d 6)NULL 7)'9/1/10 5:00' |
変更前の値と現行値が異なるため、データが見つからないというエラーが発生します。 |
|
競合を解決するためにReplicatによって適用される |
SQLバインド変数: 1)'Mary' |
|
この例では、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 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)));
UPDATEにターゲット行は存在するが、キー以外の列が異なるUPDATEROWEXISTS競合には、列に応じて2つの異なる解決を使用します。
delta_res_method解決では、salary列に対してUSEDELTA解決ロジックを使用し、値の変更が列の現行値に追加されるようにします。
DEFAULTでは、last_mod_time列を解決列として使用し、表(デフォルトの列グループ)のその他すべての列に対しUSEMAX解決ロジックを使用します。この列は行が変更されるたびに現在の時間で更新され、証跡内のこの列の値がターゲットの値と比較されます。証跡レコード内のlast_mod_timeの値がターゲット・データベースのlast_mod_timeの現行値より大きい場合は、name、phone、address、balance、commentおよびlast_mod_timeの変更がターゲットに適用されます。
COMPARECOLSでは、主キー(name列)とaddress、phone、salary、last_mod_timeの各列をUPDATE操作とDELETE操作の競合検出のための比較列として使用します。(balance列とcomment列は比較されません。)
|
注意: USEMAXのかわりにUSEMAXEQ解決を使用すると、=条件を適用できます。詳細は、『Oracle GoldenGate for Windows and UNIXリファレンス』を参照してください。 |
例外表に対するエラー処理の例は、10.2.3項「エラー処理のためのOracle GoldenGateパラメータ・ファイルの構成」を参照してください。
表10-6 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' |
|
|
証跡内の変更後イメージ |
phone='222222' address='Holly' salary=200 comment='new' last_mod_time='9/1/10 5:00' |
|
|
ターゲット・データベースのイメージ |
name='Mary' phone='1234567890' address='Oracle Pkwy' salary=600 balance=600 comment='com' last_mod_time='9/1/10 4:00' |
|
|
Replicatによって適用され、競合を検出する初期 |
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' |
|
|
|
SQLバインド変数: 1)200 2)100 3)'Mary' |
600 + (200 - 100) = 700 |
|
|
SQLバインド変数: 1)'222222' 2)'Holly' 3)'new' 4)'9/1/10 5:00' 5)'Mary' 6)'9/1/10 5:00' |
|
この例では、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 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));
UPDATEにターゲット行は存在するが、キー以外の列が異なるUPDATEROWEXISTS競合には、列に応じて2つの異なる解決を使用します。
delta_res_method解決では、salary列とbalance列に対してUSEDELTA解決ロジックを使用し、各値の変更が各列の現行値に追加されるようにします。
max_res_method解決では、address列とlast_mod_time列に対してUSEMAX解決ロジックを使用します。last_mod_time列が解決列です。この列は行が変更されるたびに現在の時間で更新され、証跡内のこの列の値がターゲットの値と比較されます。証跡レコード内のlast_mod_timeの値がターゲット・データベースのlast_mod_timeの現行値より大きい場合は、addressとlast_mod_timeの変更がターゲットに適用されます。そうでない場合、変更は無視され、ターゲット値が維持されます。
DEFAULTでは、表(デフォルトの列グループ)の残りの列(phoneとcomment)に対してIGNORE解決ロジックを使用します。Replicatでは、これらの列の変更は常に無視されます。
COMPARECOLSでは、comment列を除くすべての列を、UPDATE操作の競合検出における比較列として使用します。commentは更新のWHERE句では使用されませんが、証跡レコード内に変更前イメージを持つその他すべての列が使用されます。
|
注意: USEMAXのかわりにUSEMAXEQ解決を使用すると、=条件を適用できます。詳細は、『Oracle GoldenGate for Windows and UNIXリファレンス』を参照してください。 |
例外表に対するエラー処理の例は、10.2.3項「エラー処理のためのOracle GoldenGateパラメータ・ファイルの構成」を参照してください。
表10-7 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 |
|
|
証跡内の変更後イメージ |
phone='222222' address='Holly' salary=200 comment='new' last_mod_time='9/1/10 5:00' |
|
|
ターゲット・データベースのイメージ |
name='Mary' phone='1234567890' address='Ralston' salary=600 balance=600 comment='com' last_mod_time='9/1/10 4:00' |
|
|
Replicatによって適用され、競合を検出する初期 |
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' |
|
|
|
SQLバインド変数: 1)200 2)100 3)'Mary' |
|
|
|
SQLバインド変数: 1)'Holly' 2)'9/1/10 5:00' 3)'Mary' 4)'9/1/10 5:00' |
証跡レコード内の
|
|
|
SQLバインド変数: 1)'222222' 2)'new' 3)'Mary' |
|