主コンテンツへ
Oracle® TimesTen In-Memory Database Scaleoutユーザーズ・ガイド
リリース18.1
E98636-05
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

6 TimesTen Scaleoutでの分散トランザクションの理解

TimesTen Scaleoutでは、分散トランザクションは2フェーズ・コミットのプロトコルによって処理されます。この章では、TimesTen Scaleoutが分散トランザクションを介してACID準拠のデータベースを保守する方法について説明します。

TimesTen Scaleoutで採用されている分散トランザクション処理アルゴリズムの理解に関連する用語は、次のとおりです。

この章には次のトピックが含まれます:

トランザクション・マネージャ

アプリケーションは、データベースの1つの要素に接続することによって、TimesTen Scaleoutのデータベースに接続します。接続によって実行される各トランザクションには、トランザクション・マネージャが必要です。クライアント/サーバー・アプリケーションの場合、トランザクション・マネージャは、アプリケーションのプロキシとして機能しているTimesTen Scaleoutサーバーのスレッドです。ダイレクト・モードのアプリケーションの場合、トランザクション・マネージャは、TimesTen Scaleoutに接続するアプリケーションのスレッドです。トランザクション・マネージャは、要素(参加者)での文の実行を調整します。具体的には次を行います。

  • アプリケーションがコミットまたはロールバックを発行すると、トランザクション・マネージャは、すべての参加者が2フェーズ・コミットのプロトコルからのコミットまたはロールバックの決定に基づく一貫性のあるデータを持っていることを確認します。

  • 制約違反などのエラーが参加者に返された場合、トランザクション・マネージャは、レスポンスを調整します。トランザクション・マネージャは、TimesTen Scaleoutがユーザーに適切なエラー・メッセージを返し、すべての参加者が割り当てられたリソースを解放することを確認します。

  • 参加者に障害が発生した場合、トランザクション・マネージャは、障害が発生した参加者が一貫性のある状態にリストアするためにリカバリ時に使用する状態を作成します。

  • トランザクション・マネージャが存在する参加者に障害が発生した場合、参加者は、準備フェーズを完了したが、コミットの決定を受信しておらず、トランザクション・マネージャにアクセスできなくなっている場合、トランザクションをインダウトとして分類します。

参加者のステータス

参加者は文の実行を完了すると、トランザクション・マネージャにメッセージを送信します。メッセージには、影響を受けた行数に関する情報が含まれます。メッセージの指定内容とその処理は、次のとおりです。

  • 参加者がINSERTUPDATEDELETEなどの操作を使用して影響を受ける行を変更した場合、トランザクション・マネージャは参加者に書込み参加者としてフラグを設定します。

  • 参加者が行を変更しなかった場合、トランザクション・マネージャは参加者に読取り参加者としてフラグを設定します。

参加者の読込みまたは書込みの状態は、トランザクション・マネージャがコミット操作を処理する方法に影響します。

  • すべての参加者が読取り参加者である場合、トランザクション・マネージャは、準備フェーズを経由せずにコミットを処理します。つまり、読取り参加者は他の参加者からの合意を必要とすることなくコミット操作を実行します。

  • 1つ以上の書込み参加者がある場合、トランザクション・マネージャはコミットを2フェーズの操作として処理します。

永続性の設定

トランザクションの永続性を制御するには、Durability属性を使用します。この属性は、トランザクションが永続コミットの準備ログ・レコードを作成するかどうかを定義します。この属性の設定にかかわらず、DDL文を含むトランザクションは永続コミットの準備ログ・レコードをコミットします。Durability属性では、次の2つの値がサポートされます。

Durabilityを1に設定した場合

Durability属性を1に設定すると、参加者が分散トランザクションの永続コミットの準備ログ・レコードおよび非永続コミット・ログ・レコードを書き込みます。Durability属性を1に設定すると、コミットされたトランザクションが失敗した場合にリカバリ可能になります。これは、K-safetyが1に設定されている場合のDurability属性のデフォルト設定です。

Durability属性の詳細は、Oracle TimesTen In-Memory DatabaseリファレンスのDurabilityを参照してください。

Durabilityを0に設定した場合

Durability属性を0に設定すると、参加者が分散トランザクションの非永続コミットの準備ログ・レコードおよびコミット・ログ・レコードを書き込みます。永続性を確保するために、TimesTen Scaleoutには、通常、Durability属性が0に設定されているデータベース専用の次の新機能が用意されています。

エポック・トランザクション

エポック・トランザクションは、データベースのすべての要素間でグローバルに一貫性のあるポイントをマークする永続コミット・ログ・レコードを作成する分散トランザクションです。エポック・トランザクションは、データベースのすべての要素に永続的にコミットされます。エポック・トランザクションにより、エポック・トランザクションのタイムスタンプまでデータベースに一貫性があることが確認されます。つまり、エポック・トランザクションによって、すでにコミット・フェーズにあるトランザクションがリカバリ可能となります。


ノート:

TimesTen Scaleoutでは、Lamportタイムスタンプを使用して、データベースの別の要素でコミットするトランザクションの部分的な順序付けを提供します。各要素には、特に、準備とコミットの操作によって更新されるLamportタイムスタンプが含まれています。トランザクション・マネージャは、コミットされたすべてのトランザクションのLamportタイムスタンプをログに記録します。

TimesTen Scaleoutでは、障害が発生した要素のレプリカ・セットを含むトランザクションの永続コミットの準備ログ・レコードを、障害が発生した要素がリカバリするまで書き込むため、K-safetyが2に設定されているグリッドのトランザクションおよびDurability属性が0に設定されているデータベースは、通常、永続的です。レプリカ・セットの両方の要素で同時に障害が発生した場合にのみ、トランザクションが非永続になります。ただし、TimesTen Scaleoutでは、トランザクションをエポック・トランザクションに昇格できます。エポック・トランザクションのエポック・コミット・ログ・レコードでマークされた一貫性のある時点にデータベースをリカバリできるため、エポック・トランザクションとその前にコミットされたすべてのトランザクションには、重大な障害に対するより高いリジリエンスがあります。


ノート:


トランザクションを昇格する前に、エポック・トランザクションは、コミットの準備およびコミット・フェーズの永続ログ・レコードを作成し、トランザクションのエポック・トランザクションへの昇格の前には参加者ではなかったものを含むデータベースのすべての要素が関連するため、エポック・トランザクションのコミットは通常のトランザクションのコミットよりも負荷が高いことを考慮してください。

次の組込みプロシージャおよびシステム・ビューを使用して、エポック・トランザクションを昇格および管理します。

  • ttEpochCreate組込みプロシージャは、読取り専用トランザクションを含むトランザクションをエポック・トランザクションに昇格します。

  • ttDurableCommit組込みプロシージャは、書込みトランザクションをエポック・トランザクションに昇格します。

  • SYS.V$EPOCH_SESSIONシステム・ビューには、接続が最後から2番目のチェックポイント処理以降に作成された最新のエポック・トランザクションのLamportタイムスタンプが格納されます。

例6-1 トランザクションのエポック・トランザクションへの昇格

次の例では、書込みトランザクションのエポック・トランザクションへの昇格を示し、検証します。

Command> autocommit OFF;
Command> INSERT INTO transactions VALUES (txn_seq.NEXTVAL, 189, SYSDATE, NULL,
 'A', 5.49);
Command> SELECT epoch FROM sys.v$epoch_session;
< 1023.1 >
1 row found.
Command> CALL ttEpochCreate();
Command> COMMIT;
Command> SELECT epoch FROM sys.v$epoch_session;
< 1024.1 >
1 row found.

ttEpochCreateまたはttDurableCommit組込みプロシージャの詳細は、Oracle TimesTen In-Memory DatabaseリファレンスのそれぞれttEpochCreateまたはttDurableCommitを参照してください。

SYS.V$EPOCH_SESSIONシステム・ビューの詳細は、Oracle TimesTen In-Memory Databaseシステム表およびビュー・リファレンスのSYS.V$EPOCH_SESSIONを参照してください。

EpochInterval属性

各エポック・コミット・ログ・レコードは、各要素の特定のチェックポイント・ファイルに関連付けられます。要素に予期しない障害が発生した場合、リカバリ・プロセスでは、最新のエポック・コミット・ログ・レコードに関連付けられている各要素のチェックポイント・ファイルを使用する必要があります。このチェックポイントは、必ずしもその要素の最新のチェックポイントではありません。

最初の接続属性EpochIntervalを使用して、指定された間隔で定期エポック・トランザクションを生成するようにデータベースを構成できます。すべてのチェックポイント処理を実行するエポック・トランザクションが少なくとも1つはあるように、EpochInterval属性に設定された値は、最初の接続属性CkptFrequencyに設定されている値の半分未満である必要があります。CkptFrequency属性を0より大きい値に設定し、EpochInterval属性をCkptFrequency属性に設定された値の半分よりも大きい値に設定すると、TimesTen Scaleoutは、EpochInterval属性をCkptFrequency属性に設定された値の半分に再調整します。

EpochIntervalまたはCkptFrequency属性の詳細は、Oracle TimesTen In-Memory DatabaseリファレンスのそれぞれEpochIntervalまたはCkptFrequencyを参照してください。

CreateEpochAtCommit属性

CreateEpochAtCommit一般接続属性を使用して、エポック・トランザクションへの接続によってコミットされたすべての書込みトランザクションを昇格するように接続を構成できます。CreateEpochAtCommit属性を1に設定すると、接続時にコミットするすべてのトランザクションが、障害が発生した場合にリカバリ可能になります。ただし、エポック・トランザクションと同様に、コミット操作は、通常のトランザクションよりも負荷が高いため、重要な操作のみにCreateEpochAtCommit=1を限定することをお薦めします。


ノート:

DurableCommits属性はTimesTen Classicのデータベースを対象としていますが、この属性は、TimesTen Scaleoutのデータベースで1に設定されている場合、CreateEpochAtCommit属性の動作をエミュレートします。詳細は、Oracle TimesTen In-Memory DatabaseリファレンスのDurableCommitsを参照してください。

表6-1に示すように、Durability属性が0に設定されている場合、トランザクション・マネージャと参加者は、CreateEpochAtCommit属性の設定によって動作が異なります。

表6-1 CreateEpochAtCommitの設定に基づくコミットでの参加者の動作

CreateEpochAtCommit コミット動作

0

参加者は、分散トランザクションの非永続コミットの準備およびコミット・ログ・レコードを書き込みます。

1

すべてのトランザクションがエポック・トランザクションに昇格します。


DurabilityおよびCreateEpochAtCommit属性の両方を0に設定すると、最高のパフォーマンスが得られます。この場合は、ttEpochCreateまたはttDurableCommit組込みプロシージャを呼び出して、重要なトランザクションの永続レコードがあることを確認します。

DurabilityまたはCreateEpochAtCommit属性の詳細は、Oracle TimesTen In-Memory DatabaseリファレンスのそれぞれDurabilityまたはCreateEpochAtCommitを参照してください。ttEpochCreateまたはttDurableCommit組込みプロシージャの詳細は、Oracle TimesTen In-Memory DatabaseリファレンスのそれぞれttEpochCreateまたはttDurableCommitを参照してください。

2フェーズ・コミットのプロトコル

この項を読む前に、トランザクション・マネージャおよび永続性の設定で説明されている概念を理解していることを確認してください。

前述のとおり、分散トランザクションは2フェーズ・コミットのプロトコルに従います。TimesTen Scaleoutでは、次のように2フェーズ・コミットのプロトコルを実装します。

フェーズ0: トランザクション

  1. アプリケーションが、データベースへの接続を確立します。すべての接続は、データベースの特定の要素に関連付けられ、その接続から開始されるすべての分散トランザクションのトランザクション・マネージャとなります。

  2. アプリケーションが、1つ以上のSQL文を実行します。トランザクション・マネージャは、すべての参加者に文を送信して実行します。SQL文の実行で返された結果に基づいて、トランザクション・マネージャは参加者のステータスを識別して更新します。

  3. アプリケーションが、コミットを発行します。

フェーズ1: 準備フェーズ

  1. トランザクション・マネージャが、すべての参加者に準備メッセージを送信します。このメッセージには、トランザクション・マネージャおよびすべての参加者のIDが含まれています。

  2. 準備メッセージを受信した各参加者が、次のいずれかの操作を実行します。

    • 参加者が書込み参加者である場合は、情報を格納して、その後、トランザクションをコミットまたはロールバックするコミットの準備ログ・レコードを書き込みます。また、参加者は、読取り操作を防ぐために変更された行をロックします。

    • 参加者が読取り参加者である場合は、トランザクションを読取り専用として識別します。

  3. 参加者が、コミット決定の投票によって、トランザクション・マネージャに準備レスポンスを送信します。

    • 書込み参加者がコミットの準備ログ・レコードを書き込むことができた場合は、「Yes」のみを投票します。


      ノート:

      Durability1に設定されている場合、参加者は永続コミットの準備ログ・レコードを書き込みます。

    • 読取り参加者は、常に「Yes」を投票し、コミットの決定を待機しないでトランザクションをコミットします。この場合、コミット操作は、トランザクションに関連するすべてのロックおよび一時リソースの解放で構成されます。

フェーズ2: コミット・フェーズ

  1. トランザクション・マネージャは、トランザクションに参加するすべてのレプリカ・セット内の1つ以上の要素から準備レスポンスを受信すると、コミットの決定を含むコミットの準備ログ・レコードを書き込みます。トランザクション・マネージャでは、コミットの決定は表6-2に記載されたシナリオに基づきます。

    表6-2 コミットの決定のシナリオ

    シナリオ 意思決定

    すべての書込み参加者がその準備レスポンスで「Yes」投票を送信し、その中に各参加レプリカ・セットの1つ以上の要素があります。(失敗した参加者は、そのレプリカがレスポンスを送信するかぎり、障害が発生したとして識別されるとコミットの決定に影響を与えません。)

    コミット

    いずれかの書込み参加者が準備レスポンスで「No」投票を送信します。

    ロール・バック


  2. トランザクション・マネージャが、すべての書込み参加者にコミットの決定とともにメッセージを送信します。

  3. トランザクション・マネージャを含むすべての書込み参加者が、コミットの決定に基づいてトランザクションをコミットまたはロールバックします。

図6-1は、TimesTen Scaleoutでの分散トランザクションの2フェーズ・コミットのプロトコルの実装を示しています。

図6-1 2フェーズ・コミットのプロトコル

図6-1の説明が続きます
図6-1「2フェーズ・コミットのプロトコル」の説明

2フェーズ・コミットの障害分析

未処理の分散トランザクションのデータベースの操作に影響を与える可能性がある潜在的な障害には、複数のタイプがあります。表6-3は、これらの障害のタイプの概要を示し、TimesTen Scaleoutによる障害への対応について説明します。

表6-3 分散トランザクションの障害タイプ

障害 アクション

トランザクション・マネージャに障害が発生します。

トランザクション・マネージャに障害が発生した(アプリケーションが終了したなど)場合は、そのインスタンスのメイン・デーモンが障害を捕捉し、サブデーモンに通知します。サブデーモンは、トランザクションの状態に応じて、すべての参加者にコミットまたはロールバック・メッセージを送信します。

トランザクション・マネージャのホストに障害が発生します。

トランザクション・マネージャのホストに障害が発生すると、デーモンおよびすべてのサブデーモンに障害が発生します。各参加者は、トランザクション・マネージャへのTCP接続が閉じられるか、またはタイムアウトになったときにこの障害を認識します。

参加者は、障害を認識すると、準備フェーズに到達していないトランザクションをロールバックします。参加者がすでにその準備レスポンスを送信した場合は、他の参加者にコミットの決定を依頼し、次のいずれかのアクションを実行します。

  • 他の参加者のうち少なくとも1つがコミットの決定を受信すると、依頼元の参加者が、コミットの決定を実現します。

  • 他の参加者がコミットの決定を受信しなかった場合、依頼元の参加者は、トランザクション・マネージャのリカバリを待機します。

コミットの準備ログ・レコードを書き込む前に、参加しているレプリカ・セットのすべての要素に障害が発生します。

トランザクション・マネージャが、トランザクションのロールバックを決定します。

コミットの準備ログ・レコードの書込み後に、参加者に障害が発生します。

参加者は、リカバリ後に、他の参加者のいずれかによるコミットの決定をリクエストします。

参加者がビジー状態です。

トランザクション・マネージャは、参加者から準備レスポンスを受信するまで待機します。


分散トランザクションのトラブルシューティング

TimesTen Classicでは、トランザクションが別のトランザクションによって保持されているリソースを待機する必要がある場合があります。リソースはロックで保護されている場合、トランザクションはロックが解放されるまで待機します。他のトランザクションがデータ・ロックとして示されていない外部イベントを待機している可能性があるため、デッドロック検出によって問題が解決されません。トランザクションが待機する原因となる可能性があるリソースは、次のとおりです。

  • セマフォ待機

  • ラッチ待機

  • I/Oイベント

  • 参加者のないオープン・トランザクション

  • 長時間実行されている操作

TimesTen Scaleoutでは、これらのケースがまだ該当し、さらに別のケースである可能性もあります。要素に障害が発生すると、その要素から開始されたすべてのトランザクションでは、トランザクション・マネージャが失われています。リモート参加者は、準備レスポンスの送信後にトランザクションのコミットの決定を受信しなかった場合、インダウトになったトランザクションをコミットまたはロールバックするのを待機する必要があります。また、準備レスポンスを送信した後、コミットの決定を受け取る前に参加者に障害が発生した場合、トランザクションは障害が発生した参加者のインダウト・トランザクションになります。

グローバル・トランザクションID

グローバル・トランザクションIDは、データベースのすべての要素にわたるトランザクションを一意に識別します。グローバル・トランザクションIDは、次のパラメータで構成されます。

  • トランザクション・マネージャの要素ID

  • トランザクション・マネージャの接続IDまたはローカル・トランザクションID

  • 接続から発行されたトランザクションのカウンタ

TimesTen Scaleoutで未処理トランザクションのグローバル・トランザクションIDを取得する方法の詳細は、例6-2を参照してください。

例6-2 グローバル・トランザクションIDの取得

この例では、トランザクションを発行する接続内からグローバル・トランザクションIDを取得する方法を示しています。SYS.V$XACT_IDシステム・ビューには、トランザクションのグローバル・トランザクションIDを作成するために必要なすべてのパラメータが格納されます。

Command> autocommit 0;
Command> INSERT INTO transactions VALUES (txn_seq.NEXTVAL, 342, SYSDATE, NULL,
 'A', 8.33);
1 row inserted.
Command> SELECT elementId, xactId, counter FROM sys.v$xact_id;
< 3, 1, 148 >
1 row found.

SYS.V$XACT_IDシステム・ビューの詳細は、Oracle TimesTen In-Memory Databaseシステム表およびビュー・リファレンスのSYS.V$XACT_IDを参照してください。

インダウト・トランザクションの管理

TimesTen Scaleoutは、要素のリカバリ中にインダウト・トランザクションを自動的に解決します。トランザクションのコミットの準備ログ・レコードには、他の参加者に関する情報が含まれます。インダウト・トランザクションを解決するために、リカバリ要素は、コミットの準備ログ・レコードにリストされているいずれかの参加者からのコミットの決定をリクエストします。

トランザクション・マネージャに障害が発生した場合、TimesTen Scaleoutは、各書込みレプリカ・セットの1つの参加者が使用可能である場合はインダウト・トランザクションを解決できます。ただし、どの参加者にもコミットの決定がなく、すべての書込みレプリカ・セットが使用可能というわけではない場合、TimesTen Scaleoutは、インダウト・トランザクションを解決できません。TimesTen Scaleoutがインダウト・トランザクションを解決できなかった場合は、ttXactAdminユーティリティを使用して、トランザクションのコミットまたはロールバックを強制します。


重要:

ほとんどの場合、未解決のインダウト・トランザクションは常にロールバックする必要があります。ただし、トランザクションを外部からコミットする場合は、一貫性のあるデータベースを保証するために、使用不可の参加レプリカを除去する必要があります。レプリカ・セットの除去は、レプリカ・セットに格納されたすべてのデータが失われることを意味します。

レプリカ・セットの除去の詳細は、レプリカ・セット全体が停止するか障害が発生した場合のデータの使用不可を参照してください。


ttXactAdminユーティリティを使用して、すべての未処理トランザクションのstateを確認できます。例6-3を参照してください。トランザクションのstatein-doubtである場合は、同じユーティリティを使用してトランザクションを外部からコミットまたはロールバックできます。例6-4または例6-5をそれぞれ参照してください。

例6-3 すべての未処理トランザクションの状態の確認

この例は、コマンドを実行しているデータ・インスタンスの要素が参加者であるすべての未処理トランザクションのステータスを取得する方法を示しています。ttXactAdminユーティリティは、コマンドを実行しているデータ・インスタンスの要素に関連する情報のみを取得します。

% ttXactAdmin -connStr "DSN=database1"
2016-12-14 11:00:36.995
/disk1/databases/database1
TimesTen Release 18.1.4.1.0
ElementID 3
 
Program File Name: _ttIsql
XactID            PID     Context            State       Loghold       Last ID       
3.1.148           26247   0x13b3ff0          Active      -1.-1         [-1:2]        
 
  Resource  ResourceID           Mode  SqlCmdID             Name
  Database  0x01312d0001312d00   IX    0                    
  HashedKey ffffffffe5a341d5     SF    284478280            PAT.ACCOUNTS
  Table     2367304              IRC   284478280            PAT.ACCOUNTS
  EndScan   AAAVVUAAAA9AAAAGjO   En    284478280            PAT.TRANSACTIONS
  Table     2367320              IRC   284478280            PAT.TRANSACTIONS
 
  Begin Time: 10:59:21.695

例6-4 インダウト・トランザクションのコミット

この例では、ttXactAdminユーティリティを使用して、トランザクション3.1.148をコミットします。このコマンドは、トランザクション・マネージャが停止しており、そのレプリカ・セットがデータベースから除去された場合にのみ正常に実行されます。障害が発生したレプリカ・セットを除去する時期と方法の詳細は、停止しているレプリカ・セットからのリカバリを参照してください。

% ttXactAdmin -connStr "DSN=database1" -xactIdCommit 3.1.148

例6-5 インダウト・トランザクションのロールバック

この例では、ttXactAdminユーティリティを使用して、トランザクション3.1.148をロールバックします。

% ttXactAdmin -connStr "DSN=database1" -xactIdRollback 3.1.148

ttXactAdminユーティリティの詳細は、Oracle TimesTen In-Memory DatabaseリファレンスのttXactAdminを参照してください。