ヘッダーをスキップ

Oracle TimesTen Replication - TimesTen to TimesTen開発者および管理者ガイド リリース6.0 B25769-01 |
| 目次 | 索引

前へ | 次へ |

## レプリケーション競合の検出および解消

双方向レプリケーション・スキームで構成されたデータ・ストアの表では、レプリケーション競合が発生する可能性があります（「一般ワークロード設定」を参照）。レプリケーション競合は、双方向レプリケーション・データ・ストアでアプリケーションが同じデータ項目に対して同時にUPDATE、INSERTまたはCREATE VIEW処理を開始した場合に発生します。特別な手順を実行しなかった場合、各データ・ストアが他方のデータ・ストアで最後に行われた更新と一致しなくなる可能性があります。

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

- 更新競合: このタイプの競合は、異なるデータ・ストアで同時実行中のトランザクションが同じ表の同じ行に対して同時にUPDATEリクエストを行い、1つ以上の列に異なる値をインストールした場合に発生します。
- 一意競合: このタイプの競合は、異なるデータ・ストアで同時実行中のトランザクションが、主キーまたは一意キーは同じでも、他の1つ以上の列の値が異なる同じ表の行に対して同時にINSERTリクエストを行った場合に発生します。
- 削除競合: このタイプの競合は、あるデータ・ストアのトランザクションが行を削除し、別のデータ・ストアの同時実行トランザクションが同時に同じ行を更新または挿入した場合に発生します。現在、TimesTenでは削除/更新競合は検出できますが、削除/挿入競合は検出できません。TimesTenはいずれのタイプの削除競合も解消できません。

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

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

## 更新競合および挿入競合

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

ステップ | データ・ストアA | データ・ストアB
--- | --- | ---
初期状態 | Xが1 | Xが1
各データ・ストアのアプリケーションが同時にXを更新 | X=2に設定 | X=100に設定
各データ・ストアのレプリケーション・エ−ジェントが他方にその更新を送信 | Xをデータ・ストアBにレプリケート | Xをデータ・ストアAにレプリケート
各データ・ストアが他方の更新を受信 | レプリケーションがX=100の設定を指示 | レプリケーションがX=2の設定を指示

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

図8.1 更新競合

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

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

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

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

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

## 削除/更新競合

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

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

図8.2 更新/削除競合

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

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

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

## タイムスタンプによる解消

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

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

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

- UNIX Systemsでは、gettimeofdayシステム・コールによって返される構造体timevalからタイムスタンプ値が導出されます。この構造体は、粒度が1マイクロ秒の時刻を4バイトの単語の組合せでレポートします。実際の粒度はシステムによって異なります。
- Windows NT Systemsでは、Win32コールGetSystemTimeAsFileTimeからタイムスタンプ値が導出されます。Windows NTファイル時刻は0.1マイクロ秒の単位でレポートされますが、有効な粒度として最大10ミリ秒を指定できます。

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

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

- 保存されているレコードのタイムスタンプより更新レコードのタイムスタンプのほうが新しい場合、TimesTenは行を更新します。同じルールが挿入にも適用されます。既存の行よりレプリケートされた挿入のほうが新しい場合は、既存の行が上書きされます。
- 更新レコードのタイムスタンプと保存されているレコードのタイムスタンプが等しい場合、更新は破棄されます。同じルールが挿入にも適用されます。
- 更新レコードのタイムスタンプが保存されているレコードのタイムスタンプより古い場合、更新は破棄されます。同じルールが挿入にも適用されます。
- 行が削除されると、タイムスタンプは比較に使用できません。削除された行への更新処理は、破棄されます。ただし、あるシステムで行を削除した後、別のシステムにレプリケートし、レプリケート先のシステムで削除の後にその行が更新されていた場合、レプリケートされた削除は拒否されます。削除された行へのレプリケートされた挿入処理は、挿入として適用されます。
- 更新された行を検出できない更新は削除競合とみなされ、レポートされますが、解消はできません。

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

## タイムスタンプ比較の設定

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

- タイムスタンプ値を保持する列をレプリケート表に定義します。
- CREATE REPLICATION文のTABLE要素ごとにCHECK CONFLICTS句を含めて、タイムスタンプ列、タイムスタンプの生成方法、競合発生時の対処および競合のレポート方法を指定します。

### レプリケート表でのタイムスタンプ列の設定

レプリケート表でタイムスタンプ比較を使用するには、タイムスタンプ値を保持するBINARY(8)型のNULL値可能列を指定する必要があります。タイムスタンプ列を主キーまたは索引の一部にすることはできません。例8.1に、タイムスタンプ値を保持するBINARY(8)型の列TSTAMPを含むREPL.TAB表を示します。

##### 例8.1

    CREATE TABLE REPL.TAB (COL1 SMALLINT NOT NULL,
                           COL2 SMALLINT NOT NULL,
                           TSTAMP BINARY(8),
                           PRIMARY KEY (COL1));

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

### CHECK CONFLICTS句の設定

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

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

CREATE REPLICATION文の構文については、『Oracle TimesTen In-Memory Database APIおよびSQLリファレンス・ガイド』のSQL文に関する章を参照してください。次に、レプリケーション・スキームの設定時にCHECK CONFLICTSを使用する方法の例を示します。

##### 例8.2

この例では、例3.25の双方向レプリケーション・スキームに自動タイムスタンプ比較を設定します。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文を使用し、各レプリケート・データ・ストアに適用します。

#### 問題が発生した場合

最新のトラブルシューティング情報については、http://www.oracle.com/technology/documentation/timesten_doc.htmlにある『Oracle TimesTen In-Memory Databaseトラブルシューティング・プロシージャ・ガイド』のレプリケーションのトラブルシューティングに関する章を参照してください。

## システム・タイムスタンプ列のメンテナンス

タイムスタンプ比較が有効になっている場合は、次のように入力します。

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

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

## 競合のレポート

次のように指定してレポートをリクエストしたとします。

    CHECK CONFLICTS BY ROW TIMESTAMP
       COLUMN ColumnName
       ...
       REPORT TO 'FileName'

    競合について記述しているレポート・ファイル（FileName）にエントリが追加されます。

    障害が発生した各処理は、ヘッダーで始まるエントリの後に、競合している処理に固有の情報が続く構成でレポートにロギングされています。レポート内の各エントリは、多数の空白行で区切られています。

    ヘッダーには次の情報が含まれます。

- 競合が検出された時間
- 競合する更新を送受信したデータ・ストア
- 競合が発生した表

ヘッダーの書式は次のとおりです。

    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進形式に変換され、浮動小数点値が適切な精度およびスケールで表示されます。

    次の項では、各タイプの競合で生成されるレポートについて説明します。各例で、CREATE REPLICATION文のCHECK CONFLICTS句にON EXCEPTION ROLLBACK WORKオプションを指定して、競合しているトランザクションを強制終了します。

### 一意競合のレポート

競合が原因でレプリケート対象の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内の新しい挿入と競合しているため、レプリケート対象の挿入は破棄されます。

##### 例8.3

    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内の新しい更新と競合しているため、レプリケート対象の更新は破棄されます。

##### 例8.4

    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

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

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

- 競合している更新タプルまたは競合している削除タプル（失敗したほうのタプル）のタイムスタンプおよび値。
- 削除タプルが失敗した場合、レポートには既存のタプル（削除タプルと競合していたが、その競合の影響を受けなかった更新タプル）のタイムスタンプおよび値も含まれます。
- レコードの識別に使用されたキー列値
- 競合の検出時に行った処理（単一行更新またはトランザクション全体の破棄）。トランザクションが破棄された場合、トランザクション全体の内容がレポート・ファイルにロギングされます。

注意: 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

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

##### 例8.5

    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に、最近更新された行に対する削除で発生した削除/更新競合の出力を示します。削除より後に更新された行があるため、SUBSCRIBERDSからの削除は破棄されます。

##### 例8.6

    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:
    <A :   147>
    Transaction containing this delete skipped
    Failed transaction:
    Delete table REPL.TAB with keys:
    <A :   147>