双方向レプリケーション・スキームで構成されたデータ・ストアの表では、レプリケーション競合が発生する可能性があります(「一般ワークロード設定」を参照)。レプリケーション競合は、双方向レプリケーション・データ・ストアでアプリケーションが同じデータ項目に対して同時にUPDATE、INSERTまたはDELETE処理を開始した場合に発生します。特別な手順を実行しなかった場合、各データ・ストアが他方のデータ・ストアで最後に行われた更新と一致しなくなる可能性があります。
次の異なる3つのタイプのレプリケーション競合が発生する可能性があります。
更新、一意、削除競合の検出時にTimesTenで作成されるレポートの例は、「競合のレポート」を参照してください。
注意: | TimesTenでは、TRUNCATE TABLE文に関連する競合は検出されません。 |
図8.1に、次の表に示す状況で値Xに対して発生する更新競合の結果を示します。
注意: | 挿入の競合から発生する一意競合は、更新競合に類似したパターンになります。ただし、競合は行全体に影響します。 |
更新競合または挿入競合を確認しないでそのままにしておくと、マスターとサブスクライバのデータ・ストアは互いに同期しなくなります。正しいデータ・ストアを判断することが困難、または不可能になる場合さえあります。
更新競合では、トランザクションで多数のデータ項目が更新された場合でも、一部の項目で競合が発生する可能性があります。トランザクションの結果は、レプリケーションによって少し上書きされるのみで、ほとんどが競合の影響を受けません。このような競合を無視すると、アプリケーション・データのトランザクションの一貫性が損なわれます。
更新競合が発生した場合、および行のバージョンごとに更新された列が異なる場合は、行に対する主キー以外のフィールドがレプリケート表間で異なる場合があります。
注意: | 1つのデータ・ストア内では、ロック・プロトコルで更新競合が防止されます。一度に1つのトランザクションのみがデータ・ストアの特定の行を更新できます。ただし、レプリケーション・システムでは、各データ・ストアで独立して処理を行うことができるため、更新競合が発生する可能性があります。 |
TimesTenレプリケーションには、同時更新または挿入に対処するためにタイムスタンプ・ベースの競合解消が含まれています。タイムスタンプ・ベースの競合解消を使用することで、レプリケート・データ・ストアの同期およびトランザクションの一貫性を維持できます。
図8.2に、次の表に示す状況でRow 4に対して発生する削除/更新競合の結果を示します。
TimesTenは削除/更新競合を検出およびレポートすることはできますが、解消することはできません。このような状況では、マスターとサブスクライバのデータ・ストアは互いに同期しなくなります。
TimesTenでは、このような競合が発生した後のデータ・ストア間の同期は保証できませんが、最新のトランザクションが各データ・ストアに適用されることは保証されます。削除のタイムスタンプが更新のタイムスタンプより新しい場合は、各データ・ストアで行が削除されます。更新のタイムスタンプが削除のタイムスタンプより新しい場合は、ローカル・データ・ストアで行が更新されます。ただし、その行は他方のデータ・ストアでは削除されているため、レプリケート対象の更新は破棄されます。レポートの例は、「削除/更新競合のレポート」を参照してください。
注意: | UPDATE BY USERが使用されている表でタイムスタンプの比較が有効になっている場合は、この動作の例外となります。詳細は、「ユーザー・タイムスタンプ列のメンテナンス」を参照してください。 |
競合が発生する可能性があるレプリケート表の場合は、BINARY(8)型の特別な列を持つ表を作成して、行を挿入または最後に更新した時刻を示すタイムスタンプ値を保持します。特定の行を変更するたびにこの列にタイムスタンプ値が自動的に挿入されるようにTimesTenを設定できます(「タイムスタンプ比較の設定」を参照)。
注意: | TimesTenでは、キャッシュ・グループにキャッシュされた表とOracle間の競合解消はサポートしていません。 |
レプリケーションでのタイムスタンプ列の計算方法は、システムによって異なります。
TimesTenでは、トランザクションが更新を実行するたびにシステムによって返される時間値がレコードのINSERTまたはUPDATE時間として使用されます。そのため、単一のトランザクションによって挿入または更新された行が、異なるタイムスタンプ値を受信する場合があります。
マスターから受信した更新を適用する場合、サブスクライバ・データ・ストアのレプリケーション・エージェントは、次の方法でタイムスタンプによる解消を実行します。
注意: | 表にON EXCEPTION NO ACTIONオプションが指定されている場合、タイムスタンプ比較に失敗した更新、挿入、削除は拒否されます。このため、レプリケーションでトランザクションの処理のすべてではなく、一部が適用された場合、トランザクションの一貫性が損なわれる可能性があります。表にON EXCEPTION ROLLBACK WORKオプションが指定されている場合は、タイムスタンプ比較に失敗すると、更新のトランザクション全体がスキップされます。 |
タイムスタンプ比較を設定するには、次の手順を実行します。
レプリケート表でタイムスタンプ比較を使用するには、タイムスタンプ値を保持するBINARY(8)型のNULL値可能列を指定する必要があります。タイムスタンプ列は、CREATE TABLE文の一部として表とともに作成する必要があります。後でALTER TABLE文の一部として追加することはできません。また、タイムスタンプ列は、主キーまたは索引の一部にはできません。例8.1に、タイムスタンプ値を保持するBINARY(8)型の列TSTAMPを含むREPL.TAB表を示します。
CREATE TABLE REPL.TAB (COL1 NUMBER NOT NULL,
COL2 NUMBER NOT NULL,
TSTAMP BINARY(8),
PRIMARY KEY (COL1));
レプリケート表にタイムスタンプ値が定義されていない場合は、タイムスタンプ比較を実行して競合を検出できません。かわりに、各サイトのデータベース内の行の値に、ローカル・アプリケーションまたはレプリケーションによって行に最後に適用された更新が反映されます。
レプリケーション・スキームの設定時に、CREATE REPLICATION文の表のELEMENT記述にCHECK CONFLICTS句を含めることによって、TABLE要素にタイムスタンプ比較を設定できます。
注意: | CHECK CONFLICTS句はDATASTORE要素には指定できません。 |
CREATE REPLICATION文の構文については、『Oracle TimesTen In-Memory Database SQLリファレンス・ガイド』のSQL文に関する説明を参照してください。次に、レプリケーション・スキームの設定時にCHECK CONFLICTSを使用する方法の例を示します。
この例では、例3.24の双方向レプリケーション・スキームに自動タイムスタンプ比較を設定します。WEST_DSNおよびEAST_DSNというDSNで、タイムスタンプ列TSTAMPを含む表REPL.ACCOUNTSをレプリケートするWESTDSデータ・ストアおよびEASTDSデータ・ストアを設定します。比較に失敗した場合は、タイムスタンプが古いほうの更新を含むトランザクションを破棄します。
CREATE REPLICATION REPL.R1
ELEMENT ELEM_ACCOUNTS_1 TABLE REPL.ACCOUNTS
CHECK CONFLICTS BY ROW TIMESTAMP
COLUMN TSTAMP
UPDATE BY SYSTEM
ON EXCEPTION ROLLBACK WORK
MASTER WESTDS ON "WESTCOAST"
SUBSCRIBER EASTDS ON "EASTCOAST"
ELEMENT ELEM_ACCOUNTS_2 TABLE REPL.ACCOUNTS
CHECK CONFLICTS BY ROW TIMESTAMP
COLUMN TSTAMP
UPDATE BY SYSTEM
ON EXCEPTION ROLLBACK WORK
MASTER EASTDS ON "EASTCOAST"
SUBSCRIBER WESTDS ON "WESTCOAST";
競合解消でデータ・ストアを双方向にレプリケートした場合、各データ・ストアのレプリケート表は、同じCHECK CONFLICTS属性で設定されている必要があります。レプリケート表のCHECK CONFLICTS設定を無効化または変更する必要がある場合は、「競合検出の無効化」の説明に従ってALTER REPLICATION文を使用し、各レプリケート・データ・ストアに適用します。
タイムスタンプ比較が有効になっている場合は、次のように入力します。
CHECK CONFLICTS BY ROW TIMESTAMP
COLUMN ColumnName
UPDATE BY SYSTEM
TimesTenでは、基礎となるオペレーティング・システムによって返される現在の時間を使用してタイムスタンプ列の値が自動的にメンテナンスされます。これがデフォルトの設定です。
UPDATE BY SYSTEMを指定すると、TimesTenは次の処理を実行します。
初期ロード時、タイムスタンプ列の値はNULLのままにしておく必要があります。また、行の挿入時または更新時に、アプリケーションでタイムスタンプ列に値を指定しないでください。
ttBulkCpまたはttMigrateユーティリティを使用してTimesTen表を保存した場合、保存された行にそれらの現在のタイムスタンプ値が保持されます。その後、表がTimesTenにコピーまたは移行された場合は、コピー・ファイルまたは移行ファイルが作成された時点でタイムスタンプ列に含まれていた値が保持されます。
注意: | ttBulkCpまたはttMigrateを使用して表をコピーまたは移行した後にタイムスタンプ比較を行うようにTimesTenを設定した場合、タイムスタンプ列の初期値はNULLのままになります。レプリケーションでは、この値が設定可能な最も早い時間とみなされます。 |
表でタイムスタンプ比較が有効になっている場合は、次のように入力します。
CHECK CONFLICTS BY ROW TIMESTAMP
COLUMN ColumnName
UPDATE BY USER
アプリケーションでタイムスタンプ値をメンテナンスする必要があります。アプリケーションで使用されるタイムスタンプ値は任意に設定できますが、時間値は小さくできません。ユーザーがタイムスタンプ列を明示的に設定または更新した場合、アプリケーション指定の値が現在の時間のかわりに使用されます。
注意: | レプリケート対象の削除処理には、常にシステム生成タイムスタンプが含まれます。レプリケーションがUPDATE BY USERで設定されている場合に更新/削除競合が発生すると、2つのタイムスタンプ値が比較されて競合が解消されます。タイムスタンプが新しいほうの処理が優先されます。ユーザー・タイムスタンプの基準がシステム生成タイムスタンプの基準と異なると、予期しない結果になる場合があります。このため、削除競合の発生が予想される場合は、システム生成タイムスタンプを使用します。 |
レプリケーション・サイト間で表の同期をメンテナンスするには、TimesTenでローカル・トランザクションが実行する更新に対してもタイムスタンプ比較を行います。更新された表に自動タイムスタンプ・メンテナンスが宣言されている場合、現在のシステム時間を超えるタイムスタンプを持つレコードへの更新は禁止されます。
通常、レプリケート・システムのクロックは、他のシステムに保存されているレコードのタイムスタンプより後のタイムスタンプがローカルで更新された同じレコードに指定されるように十分に同期されています。完全に同期させることは不可能ですが、レプリケーションでは、レコードのタイムスタンプが過去にさかのぼらないようにすることによって、レプリケート・システムの表を同期されたままにするための処理を行うことができます。
TimesTenの競合検出では、判読可能なプレーン・テキスト・ファイル、またはユーザー・アプリケーションで使用されるXMLファイルに競合がレポートされるように構成できます。この項の内容は次のとおりです。
判読可能なテキスト・ファイルに競合がレポートされるようにレプリケーションを構成する(デフォルト)には、次の構文を使用します。
CHECK CONFLICTS BY ROW TIMESTAMP
COLUMN ColumnName
...
REPORT TO 'FileName' FORMAT STANDARD
各競合について記述するレポート・ファイルFileNameにエントリが追加されます。標準のレポート形式がデフォルトのため、FORMAT STANDARDという語はオプション(省略可能)です。
障害が発生した各処理は、ヘッダーで始まるエントリの後に、競合している処理に固有の情報が続く構成でレポートにロギングされています。レポート内の各エントリは、多数の空白行で区切られています。
ヘッダーには次の情報が含まれます。
ヘッダーの書式は次のとおりです。
Conflict detected at <time> on <date>
Datastore : <subscriber datastore>
Transmitting name : <master datastore>
Table : <username>.<tablename>
例:
Conflict detected at 20:08:37 on 05-17-2004
Datastore : /tmp/subscriberds
Transmitting name : MASTERDS
Table : USER1.T1
ヘッダーの後には、競合に固有の情報が続きます。データ値はASCII形式で表示されます。バイナリ・データは表示前に16進形式に変換され、浮動小数点値が適切な精度およびスケールで表示されます。
競合レポート・ファイルの詳細は、「一意競合のレポート」、「更新競合のレポート」および「削除/更新競合のレポート」を参照してください。
XMLファイルに競合がレポートされるようにレプリケーションを構成するには、次の構文を使用します。
CHECK CONFLICTS BY ROW TIMESTAMP
COLUMN ColumnName
...
REPORT TO 'FileName' FORMAT XML
レプリケーションでは、基本ファイル名FileNameを使用して2つのファイルが作成されます。FileName.xml
は、<ttrepconflictreport>
として定義されたヘッダー・ファイルで、ルート要素および競合レポート構造のXML Document Type Definition(DTD)を含んでいます。ルート要素の内部には、ファイルFileName.includeをインクルードするためのXMLディレクティブが存在し、すべての競合がこのファイルに書き込まれます。各競合は、<conflict>
タイプの一要素として書き込まれます。
競合レポート・ファイルのXML要素の詳細は、「競合レポート・ファイルのXML Document Type Definition(DTD)」を参照してください。
注意: | XML競合レポート・ファイルでログ・メンテナンスを実行する場合は、ファイルFileName.includeのみを切り捨てるか、または移動する必要があります。競合レポートを継続して正常に機能させるには、ファイルFileName.xmlは変更せずにそのままの状態にしておく必要があります。 |
競合が原因でレプリケート対象のINSERTが失敗した場合、一意競合レコードが発行されます。
レポート・ファイルの一意競合レコードには、次の情報が含まれます。
一意競合レコードの書式は、次のとおりです。
Conflicting insert tuple timestamp : <timestamp in binary format>
Existing tuple timestamp : <timestamp in binary format>
The existing tuple :
<<column value> [,<column value>. ..]>
The conflicting tuple :
<<column value> [,<column value> ...]>
The key columns for the tuple:
<<key column name> : <key column value>>
Transaction containing this insert skipped
Failed transaction:
Insert into table <user>.<table> <<column value> [,<column value>...]>
End of failed transaction
例8.3に、主キー値2で識別される行に対する一意競合の出力を示します。SUBSCRIBERDSからレプリケートされた古い挿入がMASTERDS内の新しい挿入と競合しているため、レプリケート対象の挿入は破棄されます。
Conflict detected at 13:36:00 on 03-25-2002
Datastore : /tmp/masterds
Transmitting name : SUBSCRIBERDS
Table : REPL.TAB
Conflicting insert tuple timestamp : 3C9F983D00031128
Existing tuple timestamp : 3C9F983E000251C0
The existing tuple :
< 2, 2, 3C9F983E000251C0>
The conflicting tuple :
< 2, 100, 3C9F983D00031128>
The key columns for the tuple:
<COL1 : 2>
Transaction containing this insert skipped
Failed transaction:
Insert into table REPL.TAB < 2, 100, 3C9F983D00031128>
End of failed transaction
競合が原因でレプリケート対象のUPDATEが失敗した場合、更新競合レコードが発行されます。このレコードには次の情報がレポートされます。
更新競合レコードの書式は、次のとおりです。
Conflicting update tuple timestamp : <timestamp in binary format>
Existing tuple timestamp : <timestamp in binary format>
The existing tuple :
<<column value> [,<column value>. ..]>
The conflicting update tuple :
TSTAMP :<timestamp> :<<column value> [,<column value>. ..]>
The old values in the conflicting update:
TSTAMP :<timestamp> :<<column value> [,<column value>. ..]>
The key columns for the tuple:
<<key column name> : <key column value>>
Transaction containing this update skipped
Failed transaction:
Update table <user>.<table> with keys:
<<key column name> : <key column value>>
New tuple value:
<TSTAMP :<timestamp> :<<column value> [,<column value>. ..]>
End of failed transaction
例8.4に、主キー値6で識別される行のCOL2値に対する更新競合の出力を示します。MASTERDSデータ・ストアからレプリケートされた古い更新がSUBSCRIBERDS内の新しい更新と競合しているため、レプリケート対象の更新は破棄されます。
Conflict detected at 15:03:18 on 03-25-2002
Datastore : /tmp/subscriberds
Transmitting name : MASTERDS
Table : REPL.TAB
Conflicting update tuple timestamp : 3C9FACB6000612B0
Existing tuple timestamp : 3C9FACB600085CA0
The existing tuple :
< 6, 99, 3C9FACB600085CA0>
The conflicting update tuple :
<TSTAMP :3C9FACB6000612B0, COL2 : 50>
The old values in the conflicting update:
<TSTAMP :3C9FAC85000E01F0, COL2 : 2>
The key columns for the tuple:
<COL1 : 6>
Transaction containing this update skipped
Failed transaction:
Update table REPL.TAB with keys:
<COL1 : 6>
New tuple value: <TSTAMP :3C9FACB6000612B0, COL2 : 50>
End of failed transaction
最近削除された行に対して更新を行おうとすると、削除/更新競合レコードが発行されます。このレコードには、次の情報がレポートされます。
失敗した更新との削除競合を示すレコードの書式は、次のとおりです。
Conflicting update tuple timestamp : <timestamp in binary format>
The conflicting update tuple :
TSTAMP :<timestamp> :<<column value> [,<column value>. ..]>
This transaction skipped
The tuple does not exist
Transaction containing this update skipped
Update table <user>.<table> with keys:
<<key column name> : <key column value>>
New tuple value:
<TSTAMP :<timestamp> :<<column value> [,<column value>. ..]>
End of failed transaction
例8.5に、最近削除された行に対する更新で発生した削除/更新競合の出力を示します。更新する行がないため、SUBSCRIBERDSからの更新は破棄されます。
Conflict detected at 15:27:05 on 03-25-2002
Datastore : /tmp/masterds
Transmitting name : SUBSCRIBERDS
Table : REPL.TAB
Conflicting update tuple timestamp : 3C9FB2460000AFC8
The conflicting update tuple :
<TSTAMP :3C9FB2460000AFC8, COL2 : 99>
The tuple does not exist
Transaction containing this update skipped
Failed transaction:
Update table REPL.TAB with keys:
<COL1 : 2>
New tuple value: <TSTAMP :3C9FB2460000AFC8,
COL2 : 99>
End of failed transaction
失敗した削除との更新競合を示すレコードの書式は、次のとおりです。
Conflicting binary delete tuple timestamp : <timestamp in binary format>
Existing binary tuple timestamp : <timestamp in binary format>
The existing tuple :
<<column value> [,<column value>. ..]>
The key columns for the tuple:
<<key column name> : <key column value>>
Transaction containing this delete skipped
Failed transaction:
Delete table <user>.<table> with keys:
<<key column name> : <key column value>>
End of failed transaction
例8.6に、最近更新された行に対する削除で発生した削除/更新競合の出力を示します。削除より後に更新された行があるため、MASTERDSからの削除は破棄されます。
Conflict detected at 15:27:20 on 03-25-2002
Datastore : /tmp/subscriberds
Transmitting name : MASTERDS
Table : REPL.TAB
Conflicting binary delete tuple timestamp : 3C9FB258000708C8
Existing binary tuple timestamp : 3C9FB25800086858
The existing tuple :
< 147, 99, 3C9FB25800086858>
The key columns for the tuple:
<COL1 : 147>
Transaction containing this delete skipped
Failed transaction:
Delete table REPL.TAB with keys:
<COL1 : 147>