ヘッダーをスキップ
Oracle® TimesTen In-Memory Database開発者および管理者ガイド
11gリリース2 (11.2.2)
B66443-07
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

13 レプリケーション競合の解消

この章の内容は次のとおりです。

レプリケーション競合が発生する理由

双方向レプリケーション・スキームで構成されたデータベースの表では、レプリケーション競合が発生する可能性があります。レプリケーション競合は、双方向レプリケーション・データベースでアプリケーションが同じデータ項目に対して同時に更新、挿入または削除処理を開始した場合に発生します。特別な手順を実行しなかった場合、各データベースが他方のデータベースで最後に行われた更新と一致しなくなる可能性があります。

次のタイプのレプリケーション競合が発生する可能性があります。

  • 更新競合: このタイプの競合は、異なるデータベースで同時実行中のトランザクションが同じ表の同じ行に対して同時に更新リクエストを行い、1つ以上の列に異なる値をインストールした場合に発生します。

  • 一意競合: このタイプの競合は、異なるデータベースで同時実行中のトランザクションが、主キーまたは一意キーは同じでも、他の1つ以上の列の値が異なる同じ表の行に対して同時に挿入リクエストを行った場合に発生します。

  • 削除競合: このタイプの競合は、あるデータベースのトランザクションが行を削除し、別のデータベースの同時実行トランザクションが同時に同じ行を更新または挿入した場合に発生します。現在、TimesTenでは削除/更新競合は検出できますが、削除/挿入競合は検出できません。TimesTenはいずれのタイプの削除競合も解消できません。

更新、一意、削除競合の検出時にTimesTenで作成されるレポートの例は、「競合のレポート」を参照してください。


注意:

TimesTenでは、TRUNCATE TABLE文に関連する競合は検出されません。

更新競合および挿入競合

図13-1に、次の表に示す状況で値Xに対して発生する更新競合の結果を示します。

ステップ データベースA データベースB
初期状態 Xは1です。 Xは1です。
各データベースのアプリケーションが同時にXを更新。 X=2を設定します。 X=100を設定します。
各データベースのレプリケーション・エージェントが他方のデータベースに更新を送信。 XをデータベースBにレプリケートします。 XをデータベースAにレプリケートします。
各データベースが他方のデータベースの更新を受信。 レプリケーションがX=100に設定するように指示します。 レプリケーションがX=2に設定するように指示します。


注意:

挿入の競合から発生する一意競合は、更新競合に類似したパターンになります。ただし、競合は行全体に影響します。

更新競合または挿入競合を確認しないでそのままにしておくと、マスターとサブスクライバのデータベースは互いに同期しなくなります。正しいデータベースを判断することが困難、または不可能になる場合さえあります。

更新競合では、トランザクションで多数のデータ項目が更新された場合でも、一部の項目で競合が発生する可能性があります。トランザクションの結果は、レプリケーションによって少し上書きされるのみで、ほとんどが競合の影響を受けません。このような競合を無視すると、アプリケーション・データのトランザクションの一貫性が損なわれます。

更新競合が発生した場合、および行のバージョンごとに更新された列が異なる場合は、行に対する主キー以外のフィールドがレプリケート表間で異なる場合があります。


注意:

1つのデータベース内では、ロック・プロトコルで更新競合が防止されるため、一度に1つのトランザクションのみがデータベースの特定の行を更新できます。ただし、レプリケーション・システムでは、各データベースで独立して処理を行うことができるため、更新競合が発生する可能性があります。

TimesTenレプリケーションでは、同時更新または挿入に対処するためにタイムスタンプ・ベースの競合解消が使用されます。タイムスタンプ・ベースの競合解消を使用することで、レプリケート・データベースの同期およびトランザクションの一貫性を維持できます。

削除/更新競合

図13-2に、次の表に示す状況でRow 4に対して発生する削除/更新競合の結果を示します。

ステップ データベースA データベースB
初期状態。 Row 4が存在します。 Row 4が存在します。
各アプリケーションで、Row 4に対して競合する更新および削除を同時に発行。 Row 4を更新します。 Row 4を削除します。
各データベースのレプリケーション・エージェントが他方のデータベースに削除または更新を送信。 更新をデータベースBにレプリケートします。 削除をデータベースAにレプリケートします。
各データベースが他方のデータベースから削除または更新を受信。 レプリケーションがRow 4を削除するように指示します。 レプリケーションがRow 4を更新するように指示します。

図13-2 削除/更新競合

図13-2の説明が続きます。
「図13-2 削除/更新競合」の説明

TimesTenは削除/更新競合を検出およびレポートすることはできますが、解消することはできません。このような状況では、マスターとサブスクライバのデータベースは互いに同期しなくなります。

TimesTenでは、このような競合が発生した後のデータベース間の同期は保証できませんが、最新のトランザクションが各データベースに適用されることは保証されます。削除のタイムスタンプが更新のタイムスタンプより新しい場合は、各データベースで行が削除されます。更新のタイムスタンプが削除のタイムスタンプより新しい場合は、ローカル・データベースで行が更新されます。ただし、その行は他方のデータベースでは削除されているため、レプリケート対象の更新は破棄されます。レポートの例は、「削除/更新競合のレポート」を参照してください。


注意:

UPDATE BY USERが使用されている表でタイムスタンプの比較が有効になっている場合は、この動作の例外となります。詳細は、「ユーザー・タイムスタンプ列のメンテナンスの有効化」を参照してください。

タイムスタンプを使用した競合の解消

競合が発生する可能性があるレプリケート表の場合は、BINARY(8)型の特別な列を持つ表を作成して、行を挿入または最後に更新した時刻を示すタイムスタンプ値を保持します。特定の行を変更するたびにこの列にタイムスタンプ値が自動的に挿入されるようにTimesTenを構成できます(「タイムスタンプ比較の設定」を参照)。


注意:

TimesTenでは、キャッシュ・グループにキャッシュされた表とOracle Database間の競合解消はサポートしていません。

レプリケーションでのタイムスタンプ列の計算方法は、システムによって異なります。

  • UNIXシステムでは、gettimeofdayシステム・コールによって返される構造体timevalからタイムスタンプ値が導出されます。この構造体は、粒度が1マイクロ秒の時刻を4バイトの単語の組合せでレポートします。実際の粒度はシステムによって異なります。

  • Windowsシステムでは、Win32コールGetSystemTimeAsFileTimeからタイムスタンプ値が導出されます。Windowsファイル時刻は0.1マイクロ秒の単位でレポートされますが、有効な粒度として最大10ミリ秒を指定できます。

TimesTenでは、トランザクションが各レコードを適用するときにシステムによって返される時間値が、レコードの挿入または更新時間として使用されます。そのため、単一のトランザクションによって挿入または更新された行が、異なるタイムスタンプ値を受信する場合があります。

マスターから受信したトランザクションを適用する場合、サブスクライバ・データベースのレプリケーション・エージェントは、挿入処理、更新処理、削除処理について次の方法でタイムスタンプによる解消を実行します。

  • レプリケートされたINSERT処理を適用する場合:

    • 適用されるトランザクションのタイムスタンプが既存の行のタイムスタンプよりも新しい場合、既存行が上書きされます。

    • トランザクション・レコードと保存されているレコードのタイムスタンプが同じである場合、挿入処理は破棄されます。

    • トランザクション・レコードのタイムスタンプが保存されているレコードのタイムスタンプよりも古い場合、トランザクションの挿入処理は破棄されます。

    • 保存されている行が削除されていた場合、比較に使用できるタイムスタンプがありません。以前に削除された行へのレプリケートされた挿入処理が、挿入として適用されます。

  • レプリケートされたUPDATE処理を適用する場合:

    • 適用されるトランザクション・レコードのタイムスタンプが保存されているレコードのタイムスタンプよりも新しい場合、TimesTenは行に対して更新処理を適用します。

    • トランザクション・レコードと保存されているレコードのタイムスタンプが同じである場合、更新処理は破棄されます。

    • トランザクション・レコードのタイムスタンプが保存されているレコードのタイムスタンプよりも古い場合、トランザクションの更新処理は破棄されます。

    • 保存されている行が削除されていた場合、比較に使用できるタイムスタンプがありません。削除された行に対して指定された、レプリケートされたすべての更新処理は破棄されます。

    • 更新された行を検出できない更新処理は削除競合とみなされ、レポートされますが、解消はできません。

  • レプリケートされたDELETE処理を適用する場合:

    • レプリケートされた削除処理のタイムスタンプが既存行のタイムスタンプよりも新しい場合、既存行は削除されます。

    • レプリケートされた削除処理のタイムスタンプが保存されたレコードよりも古い場合(行が最近変更された場合)、削除処理は拒否されます。


    注意:

    表にON EXCEPTION NO ACTION句が指定されている場合、タイムスタンプ比較に失敗した更新、挿入、削除処理は拒否されます。このため、レプリケーションでトランザクションの処理の(すべてではなく)一部が適用された場合、トランザクションの一貫性が損なわれる可能性があります。表にON EXCEPTION ROLLBACK WORK句が指定されている場合(デフォルト)は、タイムスタンプ比較に失敗すると、更新のトランザクション全体が拒否されます。

ローカル更新のタイムスタンプ比較

レプリケーション・サイト間で表の同期をメンテナンスするには、TimesTenでローカル・トランザクションが実行する更新に対してもタイムスタンプ比較を行います。更新された表に自動タイムスタンプ・メンテナンスが宣言されている場合、現在のシステム時間を超えるタイムスタンプを持つレコードへの更新は禁止されます。

通常、レプリケート・システムのクロックは、他のシステムに保存されているレコードのタイムスタンプより後のタイムスタンプがローカルで更新された同じレコードに指定されるように十分に同期されています。完全に同期させることは不可能ですが、レプリケーションでは、レコードのタイムスタンプが過去にさかのぼらないようにすることによって、レプリケート・システムの表を同期されたままにできます。

タイムスタンプ比較の構成

タイムスタンプ比較を構成するには、次の手順を実行します。

レプリケート表へのタイムスタンプ列の挿入

レプリケートされた表でタイムスタンプ比較を使用するには、NULL値可能なBINARY(8)型の列を指定して、タイムスタンプ値を保持する必要があります。タイムスタンプ列は、CREATE TABLE文の一部として表とともに作成する必要があります。後でALTER TABLE文の一部として追加することはできません。また、タイムスタンプ列を主キーまたは索引に含めることはできません。例13-1に、タイムスタンプ値を保持するBINARY(8)型の列tstampを含むrep.tab表を示します。

例13-1 表作成時のタイムスタンプ列の挿入

CREATE TABLE rep.tab (col1 NUMBER NOT NULL,
                      col2 NUMBER NOT NULL,
                      tstamp BINARY(8),
                      PRIMARY KEY (col1));

レプリケート表にタイムスタンプ値が定義されていない場合は、タイムスタンプ比較を実行して競合を検出できません。かわりに、各サイトのデータベース内の行の値に、ローカル・アプリケーションまたはレプリケーションによって行に最後に適用された更新が反映されます。

CHECK CONFLICTS句の構成

レプリケーション・スキームの構成時に、CREATE REPLICATION文の表の要素記述にCHECK CONFLICTS句を含めることによって、TABLE要素にタイムスタンプ比較を設定できます。


注意:

CHECK CONFLICT句はDATASTORE要素には指定できません。

構文の詳細は、『Oracle TimesTen In-Memory Database SQLリファレンス』の「CREATE REPLICATION」文と「CHECK CONFLICTS」句を参照してください。例13-2に、レプリケーション・スキームの構成時にCHECK CONFLICTSを使用する方法を示します。

例13-2 自動タイムスタンプ比較

この例では、例9-10の双方向レプリケーション・スキームに自動タイムスタンプ比較を設定します。west_dsnおよびeast_dsnというDSNで、タイムスタンプ表tstampを含む表repl.accountsをレプリケートするwestdsデータベースおよびeastdsデータベースを定義します。比較に失敗した場合は、タイムスタンプが古い方の更新を含むトランザクションを破棄します。

CREATE REPLICATION r1
ELEMENT elem_accounts_1 TABLE 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 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を構成する場合、アプリケーションでタイムスタンプ値をメンテナンスする必要があります。アプリケーションで使用されるタイムスタンプ値は任意に設定できますが、時間値は小さくできません。ユーザーがタイムスタンプ列を明示的に設定または更新した場合、アプリケーション指定の値が現在の時間のかわりに使用されます。

レプリケート対象の削除操作には、常にシステム生成タイムスタンプが含まれます。レプリケーションがUPDATE BY USERで構成されている場合に更新/削除競合が発生すると、2つのタイムスタンプ値が比較されて競合が解消され、タイムスタンプが新しい方の操作が優先されます。ユーザー・タイムスタンプの基準がシステム生成タイムスタンプの基準と異なると、予期しない結果になる場合があります。このため、削除競合の発生が予想される場合は、システム生成タイムスタンプを使用します。

競合のレポート

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_database
Transmitting name : master_database
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ファイルへの競合のレポート

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は変更せずにそのままの状態にしておく必要があります。

一意競合のレポート

競合が原因でレプリケート対象の挿入が失敗した場合、一意競合レコードが発行されます。

レポート・ファイルの一意競合レコードには、次の情報が含まれます。

  • 既存のタプル(競合しているタプルの競合相手)のタイムスタンプおよび値。

  • 競合している挿入タプル(失敗した挿入のタプル)のタイムスタンプおよび値。

  • レコードの識別に使用されたキー列値。

  • 競合の検出時に行った処理(単一行挿入またはトランザクション全体の破棄)。


    注意:

    トランザクションが破棄された場合は、トランザクション全体の内容がレポート・ファイルに記録されます。

一意競合レコードの書式は、次のとおりです。

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> <<columnvalue> [,<columnvalue>...]>
End of failed transaction

例13-3に、主キー値2で識別される行に対する一意競合の出力を示します。subscriberdsからレプリケートされた古い挿入がmasterds内の新しい挿入と競合しているため、レプリケート対象の挿入は破棄されます。

例13-3 一意競合の出力

Conflict detected at 13:36:00 on 03-25-2002
Datastore : /tmp/masterds
Transmitting name : SUBSCRIBERDS
Table : 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 TAB < 2, 100, 3C9F983D00031128>
End of failed transaction

更新競合のレポート

競合が原因でレプリケート対象の更新が失敗した場合、更新競合レコードが発行されます。このレコードでは、次の情報がレポートされます。

  • 既存のタプル(競合しているタプルの競合相手)のタイムスタンプおよび値。

  • 競合している更新タプル(失敗した更新のタプル)のタイムスタンプおよび値。

  • 古い値。この値は、競合しているタプルの元の値(更新に失敗する前の値)です。

  • レコードの識別に使用されたキー列値。

  • 競合の検出時に行った処理(単一行更新またはトランザクション全体の破棄)。


    注意:

    トランザクションが破棄された場合は、トランザクション全体の内容がレポート・ファイルに記録されます。

更新競合レコードの書式は、次のとおりです。

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

例13-4に、主キー値6で識別される行のcol2値に対する更新競合の出力を示します。masterdsデータベースからレプリケートされた古い更新がsubscriberds内の新しい更新と競合しているため、レプリケート対象の更新は破棄されます。

例13-4 更新競合の出力

Conflict detected at 15:03:18 on 03-25-2002
Datastore : /tmp/subscriberds
Transmitting name : MASTERDS
Table : 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 TAB with keys:
<COL1 : 6>
New tuple value: <TSTAMP :3C9FACB6000612B0, COL2 : 50>
End of failed transaction

削除/更新競合のレポート

最近削除された行に対して更新を行おうとすると、削除/更新競合レコードが発行されます。このレコードでは、次の情報がレポートされます。

  • 競合している更新タプルまたは競合している削除タプル(失敗した方のタプル)のタイムスタンプおよび値。

  • 削除タプルが失敗した場合、レポートには既存のタプル(削除タプルと競合していたが、その競合の影響を受けなかった更新タプル)のタイムスタンプおよび値も含まれます。

  • レコードの識別に使用されたキー列値。

  • 競合の検出時に行った処理(単一行更新またはトランザクション全体の破棄)。


    注意:

    トランザクションが破棄された場合は、トランザクション全体の内容がレポート・ファイルに記録されます。TimesTenでは、削除/挿入競合は検出できません。

失敗した更新との削除競合を示すレコードの書式は、次のとおりです。

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

例13-5に、最近削除された行に対する更新で発生した削除/更新競合の出力を示します。更新する行がないため、SUBSCRIBERDSからの更新は破棄されます。

例13-5 削除/更新競合の出力: 削除が最近である場合

Conflict detected at 15:27:05 on 03-25-2002
Datastore : /tmp/masterds
Transmitting name : SUBSCRIBERDS
Table : 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 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

例13-6に、最近更新された行に対する削除で発生した削除/更新競合の出力を示します。削除より後に更新された行があるため、masterdsからの削除は破棄されます。

例13-6 削除/更新競合の出力: 更新が最近である場合

Conflict detected at 15:27:20 on 03-25-2002
Datastore : /tmp/subscriberds
Transmitting name : MASTERDS
Table : 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 TAB with keys:
<COL1 : 147>

競合のレポートの一時停止と再開

アプリケーションが正しく動作している場合は、レプリケーションで競合が発生してレポートされることは通常ほとんどありません。ただし、負荷が高い場合に、短時間で競合が一時的に発生することがあり、特にアプリケーションの開発中は、そのようなエラーが発生する可能性があります。このような状況では、競合レポート・ファイルへの書込みが過度に発生し、大量のSNMPトラップが生成されることがあるため、ホストのパフォーマンスが低下する可能性があります。

レプリケーションの競合がホストに悪影響を与えることを避けるために、1秒当たりの競合数がユーザーが指定するしきい値を超えたときに競合のレポートを一時停止するようにレプリケーションを構成できます。また、1秒当たりの競合数がユーザーが指定するしきい値を下回ったときに競合のレポートを再開するように構成することもできます。

競合レポートの一時停止と再開が行われたことは、それぞれSNMPトラップのttRepConflictReportStoppingTrapttRepConflictReportStartingTrapを捕捉することによって、アプリケーションで検出できます。詳細は、『Oracle TimesTen In-Memory Databaseエラー・メッセージおよびSNMPトラップ』のSNMPトラップによる診断に関する説明を参照してください。

競合レポートを1秒当たりの競合数に基づいて一時停止および再開するように構成するには、レプリケーション・スキームのSTORE句に対してCONFLICT REPORTING SUSPEND ATおよびCONFLICT REPORTING RESUME AT属性を使用します。

競合のレポートが一時停止しているときにレプリケーション・エージェントが停止した場合、そのレプリケーション・エージェントが再起動すると競合のレポートも有効になります。その場合、SNMPトラップttRepConflictReportingStartingTrapは送信されません。そのため、競合レポートの一時停止のトラップを監視するアプリケーションでは、レプリケーション・エージェントの停止と起動に関連するトラップも監視する必要があります。

CONFLICT REPORTING RESUME AT0に設定した場合、レプリケーション・エージェントが再起動するまでレポートは再開されません。

例13-7に、1秒当たりの競合数が20を超えたときに競合レポートを一時停止し、競合数が10未満に下がったときに再開するレプリケーション・スキームの構成を示します。

例13-7 競合レポートのしきい値の構成

CREATE REPLICATION r1
ELEMENT elem_accounts_1 TABLE accounts
      CHECK CONFLICTS BY ROW TIMESTAMP
        COLUMN tstamp
        UPDATE BY SYSTEM
        ON EXCEPTION ROLLBACK WORK
        REPORT TO 'conflicts' FORMAT XML
  MASTER westds ON "westcoast"
  SUBSCRIBER eastds ON "eastcoast"
ELEMENT elem_accounts_2 TABLE accounts
      CHECK CONFLICTS BY ROW TIMESTAMP
        COLUMN tstamp
        UPDATE BY SYSTEM
        ON EXCEPTION ROLLBACK WORK
        REPORT TO 'conflicts' FORMAT XML
  MASTER eastds ON "eastcoast"
  SUBSCRIBER westds ON "westcoast"
STORE westds ON "westcoast"
  CONFLICT REPORTING SUSPEND AT 20
  CONFLICT REPORTING RESUME AT 10
STORE eastds ON "eastcoast"
  CONFLICT REPORTING SUSPEND AT 20
  CONFLICT REPORTING RESUME AT 10;

競合レポートのXML Document Type Definition(DTD)

TimesTenのXML形式の競合レポートは、XML 1.0仕様(http://www.w3.org/TR/REC-xml)に基づきます。レプリケーション競合レポートのXML Document Type Definition(DTD)は、レプリケーション競合のログを含む有効なXMLファイルの要素および構造を記述した一連のマークアップ宣言です。このDTDは、競合がXMLファイルにレポートされるようにレプリケーションを構成したときに作成されるXMLヘッダー・ファイル(拡張子.xmlで識別される)に含まれます。XMLを認識するユーザー・アプリケーションでは、DTDを使用してXMLレプリケーション競合レポートの残りの部分が解析されます。XML Document Type Definition(DTD)を判読および理解する方法の詳細は、http://www.w3.org/TR/REC-xmlを参照してください。

<?xml version="1.0"?>
<!DOCTYPE ttreperrorlog [
    <!ELEMENT ttrepconflictreport(conflict*) >
    <!ELEMENT repconflict        (header, conflict, scope, failedtransaction) > 
    <!ELEMENT header             (time, datastore, transmitter, table) >
    <!ELEMENT time               (hour, min, sec, year, month, day) >
    <!ELEMENT hour               (#PCDATA) >
    <!ELEMENT min                (#PCDATA) >
    <!ELEMENT sec                (#PCDATA) >
    <!ELEMENT year               (#PCDATA) >
    <!ELEMENT month              (#PCDATA) >
    <!ELEMENT day                (#PCDATA) >
    <!ELEMENT datastore          (#PCDATA) >
    <!ELEMENT transmitter        (#PCDATA) >
    <!ELEMENT table              (tableowner, tablename) >
    <!ELEMENT tableowner          (#PCDATA) >
    <!ELEMENT tablename          (#PCDATA) >
    <!ELEMENT scope              (#PCDATA) >
    <!ELEMENT failedtransaction  ((insert | update | delete)+) >
    <!ELEMENT insert             (sql) >
    <!ELEMENT update             (sql, keyinfo, newtuple) >
    <!ELEMENT delete             (sql, keyinfo) >
    <!ELEMENT sql                (#PCDATA) >
    <!ELEMENT keyinfo            (column+) >
    <!ELEMENT newtuple           (column+) >
    <!ELEMENT column             (columnname, columntype, columnvalue) >
    <!ATTLIST column               
        pos CDATA #REQUIRED >
    <!ELEMENT columnname         (#PCDATA) >
    <!ELEMENT columnvalue        (#PCDATA) >
    <!ATTLIST columnvalue 
        isnull (true | false) "false">
    <!ELEMENT existingtuple       (column+) >
    <!ELEMENT conflictingtuple    (column+) >
    <!ELEMENT conflictingtimestamp(#PCDATA) >
    <!ELEMENT existingtimestamp   (#PCDATA) >
    <!ELEMENT oldtuple            (column+) >
    <!ELEMENT conflict            (conflictingtimestamp, existingtimestamp*,
                                   existingtuple*, conflictingtuple*, 
                                   oldtuple*, keyinfo*) > 
<!ATTLIST conflict
    type (insert | update | deletedupdate | updatedeleted) #REQUIRED>
<!ENTITY logFile                  SYSTEM "Filename.include">
]>
<ttrepconflictreport>
  &logFile;
</ttrepconflictreport>

ドキュメントの本文

XML形式のレプリケーション競合レポート用の.xmlファイルは、レポートの形式を記述し、拡張子が.includeのファイルにリンクするXML Document Type Definitionを含む単なるヘッダーです。このインクルード・ファイルは、レポートの本文であり、各レプリケーション競合を個別の要素として含んでいます。これらの要素には、挿入競合、更新競合、削除/更新競合の3つのタイプがあります。競合タイプごとに、少し異なる要素構造が必要です。

一意競合の要素

一意競合は、同じキー列を持つ行が最近挿入されたため、挿入のレプリケートが正常に実行されなかった場合に発生します。一意競合の競合レポートに書き込まれる情報については、「一意競合のレポート」を参照してください。

例13-8に、例13-3の値を使用して、一意競合のXML要素の書式を示します。

例13-8 一意競合の要素

<repconflict>
    <header>
     <time>
          <hour>13</hour>
          <min>36</min>
          <sec>00</sec>
          <year>2002</year> <month>03</month>
          <day>25</day>
      </time>
      <datastore>/tmp/masterds</datastore>
      <transmitter>SUBSCRIBERDS</transmitter>
      <table>
          <tableowner>REPL</tableowner>
          <tablename>TAB</tablename>
     </table>
   </header>
   <conflict type="insert">
     <conflictingtimestamp>3C9F983D00031128</conflictingtimestamp>
     <existingtimestamp>3C9F983E000251C0</existingtimestamp>
     <existingtuple>
         <column pos="1">
           <columnname>COL1</columnname>
           <columntype>NUMBER(38)</columntype>
           <columnvalue>2</columnvalue>
         </column>
         <column pos="2">
           <columnname>COL2</columnname>
           <columntype>NUMBER(38)</columntype>
           <columnvalue>2</columnvalue>
         </column>
           <columnname>TSTAMP</columnname>
           <columntype>BINARY(8)</columntype>
           <columnvalue>3C9F983E000251C0</columnvalue>
         </column>
      </existingtuple>
      <conflictingtuple>
         <column pos="1">
           <columnname>COL1</columnname>
           <columntype>NUMBER(38)</columntype>
           <columnvalue>2</columnvalue>
        </column>
        <column pos="2">
           <columnname>COL2</columnname>
           <columntype>NUMBER(38)</columntype>
           <columnvalue>100</columnvalue>
        </column>
        <column pos="3">
           <columname>TSTAMP</columnname>
           <columntype>BINARY(8)</columntype>
           <columnvalue>3C9F983D00031128</columnvalue>
        </column>
     </conflictingtuple>
     <keyinfo>
        <column pos="1">
          <columnname>COL1</columnname>
          <columntype>NUMBER(38)</columntype>
          <columnvalue>2</columnvalue>
        </column>
    </keyinfo>
 </conflict>
 <scope>TRANSACTION</scope>
 <failedtransaction>
   <insert>
      <sql>Insert into table TAB </sql>
      <column pos="1">
         <columnname>COL1</columnname>
         <columntype>NUMBER(38)</columntype>
         <columnvalue>2</columnvalue>
      </column>
      <column pos="2">
         <columnname>COL2</columnname>
         <columntype>NUMBER(38)</columntype>
        <columnvalue>100</columnvalue>
      </column>
      <column pos="3">
         <columnname>TSTAMP</columnname>
         <columntype>NUMBER(38)</columntype>
         <columnvalue>3C9F983D00031128</columnvalue>
      </column>
    </insert>
  </failedtransaction>
</repconflict>

更新競合の要素

更新競合は、行が最近更新されたため、更新のレプリケートが正常に実行されなかった場合に発生します。更新競合の競合レポートに書き込まれる情報については、「更新競合のレポート」を参照してください。

例13-9に、例13-4の値を使用して、更新競合のXML要素の書式を示します。

例13-9 更新競合の要素

<repconflict>
    <header>
       <time>
          <hour>15</hour>
          <min>03</min>
          <sec>18</sec>
          <year>2002</year>
          <month>03</month>
          <day>25</day>
      </time>
      <datastore>/tmp/subscriberds</datastore>
      <transmitter>MASTERDS</transmitter>
      <table>
         <tableowner>REPL</tableowner>
         <tablename>TAB</tablename>
      </table>
   </header>
   <conflict type="update">
      <conflictingtimestamp>
          3C9FACB6000612B0
      </conflictingtimestamp>
      <existingtimestamp>3C9FACB600085CA0</existingtimestamp>
      <existingtuple>
        <column pos="1">
          <columnname>COL1</columnname>
          <columntype>NUMBER(38)</columntype>
          <columnvalue>6</columnvalue>
        </column>
        <column pos="2">
          <columnname>COL2</columname>
          <columntype>NUMBER(38)</columntype>
          <columnvalue>99</columnvalue>
        </column>
        <column pos="3">
          <columnname>TSTAMP</columnname>
          <columntype>BINARY(8)</columntype>
          <columnvalue>3C9FACB600085CA0></columnvalue>
        </column>
     </existingtuple>
     <conflictingtuple>
        <column pos="3">
          <columnname>TSTAMP</columnname>
          <columntype>BINARY(8)</columntype>
          <columnvalue>3C9FACB6000612B0</columnvalue>
        </column>
        <column pos="2">
          <columnname>COL2</columnname>
          <columntype>NUMBER(38)</columntype>
          <columnvalue>50</columnvalue>
        </column>
    </conflictingtuple>
    <oldtuple>
        <column pos="3">
          <columnname>TSTAMP</columnname>
          <columntype>BINARY(8)</columntype>
          <columnvalue>3C9FAC85000E01F0</columnvalue>
       </column>
       <column pos="2">
          <columnname>COL2</columnname>
          <columntype>NUMBER(38)</columntype>
          <columnvalue>2</columnvalue>
       </column>
   </oldtuple>
   <keyinfo>
       <column pos="1">
         <columnname>COL1</columnname>
         <columntype>NUMBER(38)</columntype>
         <columnvalue>6</columnvalue>
       </column>
  </keyinfo>
</conflict>
<scope>TRANSACTION</scope>
<failedtransaction>
   <update>
      <<sql>Update table TAB</sql>
      <<keyinfo>
         <column pos="1">
           <columnname>COL1</columnname>
           <columntype>NUMBER(38)</columntype>
           <columnvalue>6</columnvalue>
         </column>
      </keyinfo>
         <column pos="3">
           <columnname>TSTAMP</columnname>
           <columntype>BINARY(8)</columntype>
           <columnvalue>3C9FACB6000612B0</columnvalue>
         </column>
         <column pos="2">
           <columnname>COL2</columnname>
           <columntype>NUMBER(38)</columntype>
           <columnvalue>50</columnvalue>
         </column>
      </update>
   </failedtransaction>
</repconflict>

削除/更新競合の要素

削除/更新競合は、更新対象の行が更新を受信するデータベースですでに削除されているため、更新のレプリケートが正常に実行されなかった場合、または行が最近更新されたため、削除のレプリケートが正常に実行されなかった場合に発生します。削除/更新競合の競合レポートに書き込まれる情報については、「削除/更新競合のレポート」を参照してください。

例13-10に、例13-5の値を使用して、行が最近削除されたため、更新が正常に実行されなかった削除/更新競合のXML要素の書式を示します。

例13-10 削除/更新競合の要素: 削除が最近である場合

<repconflict>
   <header>
       <time>
          <hour>15</hour>
          <min>27</min>
          <sec>05</sec>
          <year>2002</year>
          <month>03</month>
          <day>25</day>
       </time>
       <datastore>/tmp/masterds</datastore>
       <transmitter>SUBSCRIBERDS</transmitter>
       <table>
          <tableowner>REPL</tableowner>
          <tablename>TAB</tablename>
       </table>
   </header>
   <conflict type="update">
      <conflictingtimestamp>
          3C9FB2460000AFC8
      </conflictingtimestamp>
      <conflictingtuple>
        <column pos="3">
          <columnname>TSTAMP</columnname>
          <columntype>BINARY(8)</columntype>
          <columnvalue>3C9FB2460000AFC8</columnvalue>
        </column>
        <column pos="2">
          <columnname>COL2</columnname>
          <columntype>NUMBER(38)</columntype>
          <columnvalue>99/columnvalue>
        </column>
     </conflictingtuple>
     <keyinfo>
        <column pos="1">
          <columnname>COL1</columnname>
          <columntype>NUMBER(38)</columntype>
          <columnvalue>2</columnvalue>
        </column>
    </keyinfo>
  </conflict>
  <scope>TRANSACTION</scope>
  <failedtransaction>
     <update>
       <sql>Update table TAB</sql>
   <keyinfo>
       <column pos="1">
         <columnname>COL1</columnname>
         <columntype>NUMBER(38)</columntype>
         <columnvalue>2</columnvalue>
       </column>
   </keyinfo>
       <column pos="3">
         <columnname>TSTAMP</columnname>
         <columntype>BINARY(8)</columntype>
         <columnvalue>3C9FB2460000AFC8</columnvalue>
       </column>
       <column pos="2">
         <columnname>COL2</columnname>
         <columntype>NUMBER(38)</columntype>
         <columnvalue>99</columnvalue>
       </column>
    </update>
  </failedtransaction>
</repconflict>

例13-11に、例13-6の値を使用して、行が最近更新されたため、削除が正常に実行されなかった削除/更新競合のXML要素の書式を示します。

例13-11 削除/更新競合の要素: 更新が最近である場合

<repconflict>
   <header>
       <time>
          <hour>15</hour>
          <min>27</min>
          <sec>20</sec>
          <year>2002</year>
          <month>03</month>
          <day>25</day>
       </time>
       <datastore>/tmp/masterds</datastore>
       <transmitter>MASTERDS</transmitter>
       <table>
         <tableowner>REPL</tableowner>
         <tablename>TAB</tablename>
       </table>
   </header>
   <conflict type="delete">
       <conflictingtimestamp>
            3C9FB258000708C8
       </conflictingtimestamp>
       <existingtimestamp>3C9FB25800086858</existingtimestamp>
    <existingtuple>
       <column pos="1">
          <columnname>COL1</columnname>
          <columntype>NUMBER(38)</columntype>
          <columnvalue>147</columnvalue>
       </column>
       <column pos="2">
          <columnname>COL2</columnname>
          <columntype>NUMBER(38)</columntype>
          <columnvalue>99</columnvalue>
       </column>
       <column pos="3">
          <columnname>TSTAMP</columnname>
          <columntype>BINARY(8)</columntype>
          <columnvalue>3C9FB25800086858</columnvalue>
       </column>
    </existingtuple>
    <keyinfo>
       <column pos="1">
         <columnname>COL1</columnname>
         <columntype>NUMBER(38)</columntype>
         <columnvalue>147</columnvalue>
       </column>
    </keyinfo>
  </conflict>
  <scope>TRANSACTION</scope>
  <failedtransaction>
     <delete>
        <sql>Delete from table TAB</sql>
    <keyinfo>
       <column pos="1">
         <columnname>COL1</columnname>
         <columntype>NUMBER(38)</columntype>
         <columnvalue>147</columnvalue>
       </column>
      </keyinfo>
    </delete>
  </failedtransaction>
</repconflict>