ヘッダーをスキップ

Oracle Database 管理者ガイド
11gリリース1(11.1)

E05760-03
目次
目次
索引
索引

戻る 次へ

33 分散トランザクションの管理

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

ノードのコミット・ポイント強度の指定

分散トランザクションでどのノードが最初にコミットされるかは、最も高いコミット・ポイント強度を持つデータベースによって決まります。各ノードのコミット・ポイント強度を指定するときは、準備フェーズまたはコミット・フェーズ中に障害が発生した場合に最も重要なサーバーがブロックされないようにしてください。ノードのコミット・ポイント強度は、COMMIT_POINT_STRENGTH初期化パラメータによって指定します。

デフォルト値は、オペレーティング・システムによって異なります。値の範囲は、0(ゼロ)から255までの任意の整数です。たとえば、データベースのコミット・ポイント強度を200に設定するには、そのデータベースの初期化パラメータ・ファイルに次の行を追加します。

COMMIT_POINT_STRENGTH = 200

コミット・ポイント強度は、分散トランザクションでコミット・ポイント・サイトを決定する際にのみ使用されます。

データベースのコミット・ポイント強度を設定するときは、次の点を考慮してください。

トランザクションの命名

トランザクションの命名が可能です。この機能は、特定の分散トランザクションを識別する際に便利であり、同じ目的のCOMMIT COMMENT文にかわるものです。

トランザクションに命名するにはSET TRANSACTION...NAME文を使用します。次に例を示します。

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
     NAME 'update inventory checkpoint 0';

この例は、SERIALIZABLEに等しい分離レベルを持つ新しいトランザクションをユーザーが開始し、それに'update inventory checkpoint 0'という名前を付けたことを示しています。

分散トランザクションでは、トランザクションがコミットされるときに、名前が参加サイトに送られます。トランザクション名が存在する場合は、COMMIT COMMENTがあっても無視されます。

トランザクション名は、V$TRANSACTIONビューのNAME列に表示され、トランザクションがコミットされると、DBA_2PC_PENDINGビューのTRAN_COMMENTフィールドに表示されます。

分散トランザクション情報の表示

各データベースのデータ・ディクショナリには、オープンしているすべての分散トランザクションに関する情報が格納されています。データ・ディクショナリの表とビューを使用すると、トランザクションに関する情報を取得できます。この項の内容は、次のとおりです。

準備完了トランザクションのID番号と状態の判断

次のビューには、ローカル・データベースで定義され、データ・ディクショナリに格納されているデータベース・リンクが表示されます。

ビュー  用途 

DBA_2PC_PENDING 

インダウト分散トランザクションがすべてリストされます。このビューには、インダウト・トランザクションが移入されるまで何もデータが入っていません。トランザクションが解決された後、ビューはパージされます。 

このビューは、特定のトランザクションIDのグローバル・コミット番号を判断するために使用します。このグローバル・コミット番号は、インダウト・トランザクションを手動で解決するときに使用できます。

関連性の最も高い列を次の表に示します(ビューのすべての列の詳細は、『Oracle Databaseリファレンス』を参照してください)。

表 33-1    DBA_2PC_PENDING 
  説明 

LOCAL_TRAN_ID  

integer.integer.integer」という書式のローカル・トランザクション識別子。

注意: 接続のLOCAL_TRAN_IDGLOBAL_TRAN_IDが同じ場合、そのノードはトランザクションのグローバル・コーディネータです。 

GLOBAL_TRAN_ID  

global_db_name.db_hex_id.local_tran_id」という書式のグローバル・データベース識別子。ここで、db_hex_idは、データベースを一意に識別するために使用される8文字の16進値です。この共通のトランザクションIDは、1つの分散トランザクションに関係するすべてのノードで同じです。

注意: 接続のLOCAL_TRAN_IDGLOBAL_TRAN_IDが同じ場合、そのノードはトランザクションのグローバル・コーディネータです。 

STATE  

STATEに可能な値は、次のとおりです。

  • Collecting

    通常、このカテゴリは、グローバル・コーディネータまたはローカル・コーディネータにのみ適用されます。ノードは現在他のデータベース・サーバーから情報を収集中であり、その後ノード自身が準備できるかどうかが判断されます。

  • 準備完了

    ノードは準備を完了していますが、そのことをローカル・コーディネータに準備完了メッセージで通知しているかどうかは不明です。しかし、コミット要求はまだ受け取っていません。ノードは準備完了状態にあり、トランザクションのコミットに必要なローカル・リソースのロックをすべて保持しています。

  • Committed

    ノード(任意のタイプ)はトランザクションのコミットを完了していますが、トランザクションに関係している他のノードが同じように完了していない可能性があります。つまり、トランザクションは1つ以上のノードでまだ保留しています。

  • Forced Commit

    ペンディング・トランザクションは、データベース管理者(DBA)の判断で強制的にコミットできます。このエントリは、ローカル・ノードでトランザクションが手動でコミットされた場合に表示されます。

  • Forced termination (rollback)

    ペンディング・トランザクションは、DBAの判断で強制的にロールバックできます。このエントリは、ローカル・ノードでこのトランザクションが手動でロールバックされた場合に表示されます。

 

MIXED  

YESは、トランザクションの一部があるノードではコミットされ、別のノードではロールバックされたことを示します。 

TRAN_COMMENT  

トランザクションがコミットされると、トランザクション・コメントまたはトランザクション名(トランザクションに命名している場合)がこの列に設定されます。 

HOST  

ホスト・マシンの名前。 

COMMIT#  

コミットされたトランザクションのグローバル・コミット番号。 

DBA_2PC_PENDINGの関連情報を問い合せるには、次のスクリプトpending_txn_scriptを実行します(出力例も含まれています)。

COL LOCAL_TRAN_ID FORMAT A13
COL GLOBAL_TRAN_ID FORMAT A30
COL STATE FORMAT A8
COL MIXED FORMAT A3
COL HOST FORMAT A10
COL COMMIT# FORMAT A10

SELECT LOCAL_TRAN_ID, GLOBAL_TRAN_ID, STATE, MIXED, HOST, COMMIT#
   FROM DBA_2PC_PENDING
/

SQL> @pending_txn_script

LOCAL_TRAN_ID GLOBAL_TRAN_ID                 STATE    MIX HOST       COMMIT#
------------- ------------------------------ -------- --- ---------- ----------
1.15.870      HQ.ACME.COM.ef192da4.1.15.870  commit   no  dlsun183   115499

この出力は、ローカル・トランザクション1.15.870がこのノードではコミットを完了しているものの、他の1つ以上のノードで保留している可能性があることを示しています。LOCAL_TRAN_IDGLOBAL_TRAN_IDのローカル部分が同じなので、このノードはトランザクションのグローバル・コーディネータです。

インダウト・トランザクションのセッション・ツリーのトレース

次のビューには、リモート・クライアントから受信されるインダウト・トランザクションと、リモート・サーバーに送信されるインダウト・トランザクションが表示されます。

ビュー  用途 

DBA_2PC_NEIGHBORS 

インダウト分散トランザクションについて、リモート・クライアントから受信されるものとリモート・サーバーに送信されるものがすべてリストされます。また、ローカル・ノードがトランザクションのコミット・ポイント・サイトかどうかも示されます。

このビューには、インダウト・トランザクションが移入されるまで何もデータが入っていません。トランザクションが解決された後、ビューはパージされます。 

トランザクションがインダウトのときは、セッション・ツリー内のどのノードがどのロールを実行しているのかを判断することが必要な場合があります。このビューを使用すると、次のことが判断できます。

関連性の最も高い列を次の表に示します(ビューのすべての列の詳細は、『Oracle Databaseリファレンス』を参照してください)。

表 33-2    DBA_2PC_NEIGHBORS 
  説明 

LOCAL_TRAN_ID  

integer.integer.integer」という書式のローカル・トランザクション識別子。

注意: 接続のLOCAL_TRAN_IDGLOBAL_TRAN_ID.DBA_2PC_PENDINGが同じ場合、そのノードはトランザクションのグローバル・コーディネータです。 

IN_OUT  

受信トランザクションの場合はIN、送信トランザクションの場合はOUTです。 

DATABASE  

受信トランザクションの場合は、このローカル・ノードから情報を要求したクライアント・データベースの名前です。送信トランザクションの場合は、リモート・サーバーの情報へのアクセスに使用されたデータベース・リンクの名前です。 

DBUSER_OWNER  

受信トランザクションの場合は、リモート・データベース・リンクによる接続で使用されるローカル・アカウントです。送信トランザクションの場合は、データベース・リンクの所有者です。 

INTERFACE  

Cはコミット・メッセージ、Nは準備完了状態を示すメッセージまたは読取り専用コミットの要求のどちらかです。

IN_OUTOUTの場合、Cは、接続のリモート側の子がコミット・ポイント・サイトであり、コミットと終了のどちらを実行するかを知っていることを意味します。Nは、ローカル・ノードの準備が完了したことをリモート・ノードに通知中であることを意味します。

IN_OUTINの場合、Cは、送信接続のリモート側のローカル・ノードまたはデータベースがコミット・ポイント・サイトであることを表します。Nは、リモート・ノードの準備が完了したことをローカル・ノードに通知中であることを意味します。 

DBA_2PC_PENDINGの関連情報を問い合せるには、次のスクリプトneighbors_scriptを実行します(出力例も含まれています)。

COL LOCAL_TRAN_ID FORMAT A13
COL IN_OUT FORMAT A6
COL DATABASE FORMAT A25
COL DBUSER_OWNER FORMAT A15
COL INTERFACE FORMAT A3
SELECT LOCAL_TRAN_ID, IN_OUT, DATABASE, DBUSER_OWNER, INTERFACE 
   FROM DBA_2PC_NEIGHBORS
/

SQL> CONNECT SYS@hq.acme.com AS SYSDBA
SQL> @neighbors_script

LOCAL_TRAN_ID IN_OUT DATABASE                  DBUSER_OWNER    INT
------------- ------ ------------------------- --------------- ---
1.15.870      out    SALES.ACME.COM            SYS             C

この出力は、トランザクション1.15.870をコミットするための送信要求をローカル・ノードがリモート・サーバーsalesに送ったことを示します。salesがトランザクションをコミットしたものの、他のノードがコミットしなかった場合は、salesがコミット・ポイント・サイトであることが判明します。コミット・ポイント・サイトは、常に最初にコミットされるためです。

インダウト・トランザクションの処理方法の決定

2フェーズ・コミットの間に障害が発生すると、トランザクションはインダウトになります。分散トランザクションがインダウトになる要因は、次のとおりです。

ローカルのインダウト分散トランザクションは、手動で強制的にコミットまたはロールバックできます。この操作では一貫性の問題が生じる可能性があるため、特定の条件が成り立つとき以外は実行しないでください。

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

2フェーズ・コミットに関する問題の検出

分散トランザクションをコミットするユーザー・アプリケーションには、次のいずれかのエラー・メッセージによって問題が通知されます。

ORA-02050: トランザクションIDはロールバックされました。
           some remote dbs may be in-doubt
ORA-02053: トランザクションIDはコミットしました。
           some remote dbs may be in-doubt
ORA-02054: トランザクションIDはインダウトです

アプリケーションでこれらのエラーを受け取った場合は、トランザクションに関する情報を保存するようにしてください。この情報は、後で分散トランザクションの手動リカバリが必要になった場合に使用できます。

ネットワークまたはシステムの障害のために、任意のノードでインダウト分散トランザクションが1つ以上発生した場合でも、そのノードの管理者がなんらかの処理を実行する必要はありません。ネットワークやシステムの障害が解決した後、データベースの自動リカバリ機能によって、セッション・ツリーのすべてのノードが同じ結果になるように(つまり、すべてコミットされるかすべてロールバックされる)、すべてのインダウト・トランザクションの処理が透過的に完了します。

ただし、障害が長期にわたる場合には、トランザクションを強制的にコミットまたはロールバックすることで、ロックされたデータをすべて解放できます。アプリケーションは、この操作を想定しておく必要があります。

手動上書きを実行するかどうかの判断

次の条件が成り立つときのみ、特定のインダウト・トランザクションを手動で上書きしてください。

通常は、他の場所の管理者と相談した上で、インダウト分散トランザクションを強制的にローカルに処理するかどうかを決めてください。判断を誤った場合は、トレースの困難なデータベースの非一貫性が生じる可能性があります。この非一貫性は、手動で訂正する必要があります。

前述の条件が当てはまらない場合は、必ずデータベースの自動リカバリ機能によってトランザクションを完了するようにしてください。しかし、前述のいずれかの条件に当てはまる場合には、インダウト・トランザクションのローカルでの修正を検討してください。

トランザクション・データの分析

トランザクションの強制完了を決めた場合は、次の目的に留意しながら、使用可能な情報を分析します。

コミットまたはロールバックされたノードの特定

DBA_2PC_PENDINGビューを使用し、トランザクションをコミットまたはロールバックしたノードを探します。トランザクションをすでに解決しているノードが見つかった場合は、そのノードで実行された処理に従うことができます。

トランザクション・コメントの確認

DBA_2PC_PENDINGTRAN_COMMENT列に、対象の分散トランザクションに関するなんらかの情報が与えられていないかを確認します。コメントは、COMMIT文のCOMMENT句で指定されます。また、トランザクションに命名している場合は、トランザクションがコミットされたときに、トランザクション名がTRAN_COMMENTフィールドに設定されます。

たとえば、インダウト分散トランザクションのコメントで、トランザクションの開始元とタイプを示すことができます。

COMMIT COMMENT 'Finance/Accts_pay/Trans_type 10B';

また、この情報をトランザクション名として提供するために、SET TRANSACTION...NAME文を使用することも可能です。

関連項目:

「トランザクションの命名」 

トランザクション・アドバイスの確認

DBA_2PC_PENDINGADVICE列に、対象の分散トランザクションに関するなんらかの情報が与えられていないかを確認します。アプリケーションでALTER SESSION文のADVISE句を使用すれば、分散トランザクションの別々の部分を強制的にコミットまたはロールバックする際のアドバイスを規定できます。

準備フェーズ中に各ノードに送られたアドバイスは、現行トランザクション内でそのデータベースに対し最新のDML文が実行されたときに有効なアドバイスです。

たとえば、あるノードのemp表から別のノードのemp表に従業員レコードを移動する分散トランザクションを考えます。次の一連のSQL文を追加することによって、管理者が各ノードで個別にインダウト・トランザクションを強制的に完了した場合でも、トランザクションでレコードを保護できます。

ALTER SESSION ADVISE COMMIT;
INSERT INTO emp@hq ... ;    /*advice to commit at HQ */
ALTER SESSION ADVISE ROLLBACK;
DELETE FROM emp@sales ... ; /*advice to roll back at SALES*/

ALTER SESSION ADVISE NOTHING;

与えられたアドバイスに従ってインダウト・トランザクションを手動で強制的に完了すると、最悪の場合、各ノードに従業員レコードがコピーされ、消去できなくなる可能性があります。

インダウト・トランザクションの手動上書き

COMMIT文またはROLLBACK文に、FORCEオプションと、コミットまたはロールバックするインダウト・トランザクションのローカル・トランザクションIDまたはグローバル・トランザクションIDを示すテキスト文字列を指定します。


注意:

以降のすべての例で、トランザクションはローカル・ノードでコミットまたはロールバックされます。ローカルのペンディング・トランザクション表では、このトランザクションの行のSTATE列に強制コミットまたは強制終了の値が記録されます。 


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

インダウト・トランザクションの手動コミット

トランザクションのコミットを試みる前に、適正な権限を持っていることを確認してください。必要な権限は次のとおりです。

トランザクションをコミットするユーザー  必要な権限 

管理者 

FORCE TRANSACTION  

別のユーザー 

FORCE ANY TRANSACTION  

トランザクションIDのみを使用したコミット

次のSQL文は、インダウト・トランザクションをコミットします。

COMMIT FORCE 'transaction_id';

変数transaction_idは、DBA_2PC_PENDINGデータ・ディクショナリ・ビューのLOCAL_TRAN_ID列またはGLOBAL_TRAN_ID列のどちらかで指定されているトランザクション識別子です。

たとえば、DBA_2PC_PENDINGを問い合せて、分散トランザクションのLOCAL_TRAN_ID1:45.13であることを確認するとします。

そして、次のSQL文を発行し、このインダウト・トランザクションのコミットを強制実行します。

COMMIT FORCE '1.45.13';

システム変更番号(SCN)を使用したコミット

必要であれば、トランザクションを強制的にコミットするときに、トランザクションのSCNを指定することもできます。この機能を使用すると、他のノードでトランザクションがコミットされたときに割り当てられたSCNを使用して、インダウト・トランザクションをコミットできます。

これにより、障害が発生した場合でも、分散トランザクションのコミット時間の同期を保つことができます。SCNは、別のノードですでにコミットされた同じトランザクションのSCNが判別できるときのみ指定してください。

たとえば、次のグローバル・トランザクションIDを使用してトランザクションを手動でコミットするとします。

SALES.ACME.COM.55d1c563.1.93.29 

まず、対象のトランザクションに関係しているリモート・データベースのDBA_2PC_PENDINGビューを問い合せます。次に、そのノードでトランザクションのコミットに使用されたSCNをメモします。そして、ローカル・ノードでトランザクションをコミットするときにこのSCNを指定します。たとえば、SCNが829381993の場合は、次の文を発行します。

COMMIT FORCE 'SALES.ACME.COM.55d1c563.1.93.29', 829381993;

関連項目:

COMMIT文の使用の詳細は、『Oracle Database SQLリファレンス』を参照してください。 

インダウト・トランザクションの手動ロールバック

インダウト分散トランザクションのロールバックを試みる前に、適正な権限を持っていることを確認してください。必要な権限は次のとおりです。

トランザクションをコミットするユーザー  必要な権限 

管理者 

FORCE TRANSACTION  

別のユーザー 

FORCE ANY TRANSACTION  

次のSQL文は、インダウト・トランザクションをロールバックします。

ROLLBACK FORCE 'transaction_id';

変数transaction_idは、DBA_2PC_PENDINGデータ・ディクショナリ・ビューのLOCAL_TRAN_ID列またはGLOBAL_TRAN_ID列のどちらかで指定されているトランザクション識別子です。

たとえば、ローカル・トランザクションIDが2.9.4のインダウト・トランザクションをロールバックするには、次の文を使用します。

ROLLBACK FORCE '2.9.4';


注意:

インダウト・トランザクションをセーブポイントまでロールバックすることはできません。 


関連項目:

ROLLBACK文の使用の詳細は、『Oracle Database SQLリファレンス』を参照してください。 

データ・ディクショナリからの保留行のパージ

インダウト・トランザクションは、RECO(リカバラ・プロセス)によってリカバリされる前に、DBA_2PC_PENDING.STATE列にCOLLECTINGCOMMITTEDまたはPREPAREDとして表示されます。COMMIT FORCEまたはROLLBACK FORCEを使用してインダウト・トランザクションを強制的に完了すると、FORCED COMMITまたはFORCED ROLLBACKの状態になることがあります。

自動リカバリでは通常、これらの状態にあるエントリが削除されます。唯一の例外として、リカバリ時に、トランザクション内の他のサイトと一貫性のない状態にある強制トランザクションが検出されるときがあります。この場合は、エントリが表内に残る可能性があり、DBA_2PC_PENDINGMIXED列の値がYESになります。これらのエントリは、DBMS_TRANSACTION.PURGE_MIXEDプロシージャを使用してクリーンアップできます。

リモート・データベースが永続的に失われたために自動リカバリが不可能な場合は、データベースを再作成してもリカバリではそのデータベースを識別できません。これは、再作成時に新しいデータベースIDが割り当てられるためです。この場合は、DBMS_TRANSACTIONパッケージのPURGE_LOST_DB_ENTRYプロシージャを使用して、エントリをクリーンアップする必要があります。このエントリによってデータベース・リソースが保持されることはないため、エントリのクリーンアップを急ぐ必要はありません。

関連項目:

DBMS_TRANSACTIONパッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 

PURGE_LOST_DB_ENTRYプロシージャの実行

エントリをデータ・ディクショナリから手動で削除するには、次の構文を使用します(ここで、trans_idはトランザクションの識別子を表します)。

DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('trans_id');

たとえば、保留中の分散トランザクション1.44.99をパージするには、SQL*Plusで次の文を入力します。

EXECUTE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('1.44.99');

このプロシージャは、自動リカバリによってトランザクションを解決できないほどの大幅な再構成を行った場合にのみ実行してください。たとえば、次のような場合です。

DBMS_TRANSACTIONを使用する時期の判断

次の表は、分散トランザクションに関する各種の状態と、それに対して管理者が実行すべき処理を示したものです。

STATE列  グローバル・
トランザクションの状態
 
ローカル・
トランザクションの状態
 
通常の処理  代替処理 

Collecting 

Rolled back 

Rolled back 

なし 

PURGE_LOST_DB_ENTRY(自動リカバリでトランザクションを解決できない場合のみ) 

Committed 

Committed 

Committed 

なし 

PURGE_LOST_DB_ENTRY(自動リカバリでトランザクションを解決できない場合のみ) 

準備完了 

Unknown 

準備完了 

なし 

強制コミットまたは強制ロールバック 

Forced commit 

Unknown 

Committed 

なし 

PURGE_LOST_DB_ENTRY(自動リカバリでトランザクションを解決できない場合のみ) 

Forced rollback 

Unknown 

Rolled back 

なし 

PURGE_LOST_DB_ENTRY(自動リカバリでトランザクションを解決できない場合のみ) 

Forced commit 

Mixed 

Committed 

非一貫性部分を手動で削除してからPURGE_MIXEDを使用する 

Forced rollback 

Mixed 

Rolled back 

非一貫性部分を手動で削除してからPURGE_MIXEDを使用する 

インダウト・トランザクションの手動コミット: 例

図33-1は、分散トランザクションのコミット中の障害を示しています。この障害例では、準備フェーズは完了しています。しかし、コミット・フェーズ時に、コミット・ポイント・サイトがトランザクションをコミットしていても、コミット・ポイント・サイトのコミット確認がグローバル・コーディネータに到達しません。インダウト・トランザクションは他のトランザクションにとっても重要なものであるため、在庫データはロックされており、アクセスできません。また、インダウト・トランザクションがコミットまたはロールバックされるまで、ロックが必ず保持されます。

図 33-1    インダウト分散トランザクションの例


画像の説明

次の手順に従って、インダウト・トランザクションのローカル部分を手動で強制完了できます。詳細は、以降の項を参照してください。

手順1: ユーザーからのフィードバックの記録

手順2: DBA_2PC_PENDINGの問合せ

手順3: ローカル・ノードでのDBA_2PC_NEIGHBORSの問合せ

手順4: 全ノードでのデータ・ディクショナリ・ビューの問合せ

手順5: インダウト・トランザクションのコミット

手順6: DBA_2PC_PENDINGを使用したMIXED結果のチェック

手順1: ユーザーからのフィードバックの記録

インダウト・トランザクションのロックと競合を起こしているローカル・データベース・システムのユーザーは、次のエラー・メッセージを受け取ります。

ORA-01591: インダウト分散トランザクション1.21.17がロックを保持しています。

この場合、1.21.17はインダウト分散トランザクションのローカル・トランザクションIDです。どのインダウト・トランザクションを強制処理すればよいかを特定するために、問題を報告したユーザーからこのID番号を聞き、記録しておきます。

手順2: DBA_2PC_PENDINGの問合せ

SQL*Plusを使用してwarehouseに接続した後、ローカルのDBA_2PC_PENDINGデータ・ディクショナリ・ビューを問い合せて、インダウト・トランザクションに関する情報を取得します。

CONNECT SYS@warehouse.acme.com AS SYSDBA
SELECT * FROM DBA_2PC_PENDING WHERE LOCAL_TRAN_ID = '1.21.17';

データベースは次の情報を返します。

Column Name            Value
---------------------- --------------------------------------
LOCAL_TRAN_ID          1.21.17
GLOBAL_TRAN_ID         SALES.ACME.COM.55d1c563.1.93.29
STATE                  prepared
MIXED                  no
ADVICE
TRAN_COMMENT           Sales/New Order/Trans_type 10B
FAIL_TIME              31-MAY-91
FORCE_TIME
RETRY_TIME             31-MAY-91
OS_USER                SWILLIAMS
OS_TERMINAL            TWA139:
HOST                   system1
DB_USER                SWILLIAMS
COMMIT#

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

グローバル・トランザクションIDは、分散トランザクションのすべてのノードで同一である共通のトランザクションIDです。次のような書式で記録されています。

global_database_name.hhhhhhhh.local_transaction_id

各項目の意味は次のとおりです。

グローバル・コーディネータでは、グローバル・トランザクションIDの最後の部分とローカル・トランザクションIDが一致します。この例ではこれらの番号が一致しないので、warehouseはグローバル・コーディネータでないことがわかります。

LOCAL_TRAN_ID          1.21.17
GLOBAL_TRAN_ID         ... 1.93.29

トランザクションの状態の判断

このノードのトランザクションは、準備完了状態です。

STATE          prepared 

したがって、warehouseは、自身のコーディネータからコミット要求またはロールバック要求が送られてくるのを待っています。

コメントまたはアドバイスの確認

トランザクションのコメントまたはアドバイスに、このトランザクションに関する情報が含まれている可能性があります。トランザクションに関する情報が含まれていれば、そのコメントを利用します。この例では、トランザクションのコメントに開始元とトランザクション・タイプが含まれています。

TRAN_COMMENT           Sales/New Order/Trans_type 10B

また、SET TRANSACTION...NAME文によって、トランザクションに関する情報がトランザクション名として提供されている可能性もあります。

この情報から、トランザクションのローカル部分をコミットすべきか、またはロールバックすべきかを決める際に役立つ情報を得ることができます。インダウト・トランザクションに有益なコメントが付けられていない場合は、その他の管理作業を実行し、セッション・ツリーをトレースして、トランザクションをすでに解決しているノードを探す必要があります。

手順3: ローカル・ノードでのDBA_2PC_NEIGHBORSの問合せ

この手順の目的は、セッション・ツリーを探索してコーディネータを見つけ、最終的にグローバル・コーディネータに到達することです。それと同時に、トランザクションをすでに解決しているコーディネータが見つかる場合もあります。トランザクションをすでに解決しているコーディネータが見つからない場合は、最終的にコミット・ポイント・サイトを探し出します。コミット・ポイント・サイトでは、常にインダウト・トランザクションが解決されています。セッション・ツリーをトレースするには、各ノードのDBA_2PC_NEIGHBORSビューを問い合せます。

この例では、warehouseデータベースでこのビューを問い合せます。

CONNECT SYS@warehouse.acme.com AS SYSDBA
SELECT * FROM DBA_2PC_NEIGHBORS
  WHERE LOCAL_TRAN_ID = '1.21.17'
  ORDER BY SESS#, IN_OUT;

Column Name            Value
---------------------- --------------------------------------
LOCAL_TRAN_ID          1.21.17
IN_OUT                 in
DATABASE               SALES.ACME.COM
DBUSER_OWNER           SWILLIAMS
INTERFACE              N
DBID                   000003F4
SESS#                  1
BRANCH                 0100

データベースのロールとデータベース・リンク情報の取得

DBA_2PC_NEIGHBORSビューは、インダウト・トランザクションに対応付けられた接続に関する情報を提供します。情報は、接続が受信IN_OUT = in)か送信IN_OUT = out)かによって異なります。

IN_OUT  意味  DATABASE  DBUSER_OWNER 

in 

このノードは別のノードのサーバーです。 

このノードに接続しているクライアント・データベースの名前がリストされます。 

インダウト・トランザクションに対応するデータベース・リンク接続のローカル・アカウントがリストされます。 

out 

このノードは他のサーバーのクライアントです。 

リモート・ノードに接続しているデータベース・リンクの名前がリストされます。 

インダウト・トランザクションのデータベース・リンクの所有者がリストされます。 

この例では、IN_OUT列によって、warehouseデータベースがsalesクライアント(DATABASE列に示されている)のサーバーであることがわかります。

IN_OUT                 in
DATABASE               SALES.ACME.COM

warehouseへの接続は、swilliamsアカウント(DBUSER_OWNER列に示されている)からのデータベース・リンクを介して確立されています。

DBUSER_OWNER           SWILLIAMS

コミット・ポイント・サイトの判別

この他、INTERFACE列によって、ローカル・ノードまたは下位ノードがコミット・ポイント・サイトなのかどうかがわかります。

INTERFACE              N

INTERFACE列が示すように、warehouseもその子もコミット・ポイント・サイトではありません。

手順4: 全ノードでのデータ・ディクショナリ・ビューの問合せ

この時点で、各設置ノードの管理者に連絡を取り、グローバル・トランザクションIDを使用して手順2および3を繰り返すように各管理者に依頼できます。


注意:

これらのノードに別のネットワークを介して直接接続できる場合は、手順2および3を独力で実行できます。 


たとえば、salesおよびhqで手順2および3を実行すると、次の結果が返されます。

salesでのペンディング・トランザクションの状態の確認

この段階では、salesの管理者がDBA_2PC_PENDINGデータ・ディクショナリ・ビューを問い合せます。

SQL> CONNECT SYS@sales.acme.com AS SYSDBA
SQL> SELECT * FROM DBA_2PC_PENDING
   > WHERE GLOBAL_TRAN_ID = 'SALES.ACME.COM.55d1c563.1.93.29';

Column Name            Value
---------------------- --------------------------------------
LOCAL_TRAN_ID          1.93.29
GLOBAL_TRAN_ID         SALES.ACME.COM.55d1c563.1.93.29
STATE                  prepared
MIXED                  no
ADVICE
TRAN_COMMENT           Sales/New Order/Trans_type 10B
FAIL_TIME              31-MAY-91
FORCE_TIME
RETRY_TIME             31-MAY-91
OS_USER                SWILLIAMS
OS_TERMINAL            TWA139:
HOST                   system1
DB_USER                SWILLIAMS
COMMIT#

salesでのコーディネータとコミット・ポイント・サイトの判別

次に、salesの管理者はDBA_2PC_NEIGHBORSを問い合せて、グローバル・コーディネータ、ローカル・コーディネータおよびコミット・ポイント・サイトを判別します。

SELECT * FROM DBA_2PC_NEIGHBORS
   WHERE GLOBAL_TRAN_ID = 'SALES.ACME.COM.55d1c563.1.93.29'
   ORDER BY SESS#, IN_OUT;

この問合せは、次の3行を返します。

warehouse接続の行に対応する情報を、書式を変えて示すと次のようになります。

Column Name            Value
---------------------- --------------------------------------
LOCAL_TRAN_ID          1.93.29
IN_OUT                 OUT
DATABASE               WAREHOUSE.ACME.COM
DBUSER_OWNER           SWILLIAMS
INTERFACE              N
DBID                   55d1c563
SESS#                  1
BRANCH                 1

hq接続の行に対応する情報を、書式を変えて示すと次のようになります。

Column Name            Value
---------------------- --------------------------------------
LOCAL_TRAN_ID          1.93.29
IN_OUT                 OUT
DATABASE               HQ.ACME.COM
DBUSER_OWNER           ALLEN
INTERFACE              C
DBID                   00000390
SESS#                  1
BRANCH                 1

前の問合せから得られた情報によって、次のことがわかります。

HQでのペンディング・トランザクションの状態の確認

この段階では、hqの管理者がDBA_2PC_PENDINGデータ・ディクショナリ・ビューを問い合せます。

SELECT * FROM DBA_2PC_PENDING@hq.acme.com
   WHERE GLOBAL_TRAN_ID = 'SALES.ACME.COM.55d1c563.1.93.29';

Column Name            Value
---------------------- --------------------------------------
LOCAL_TRAN_ID          1.45.13
GLOBAL_TRAN_ID         SALES.ACME.COM.55d1c563.1.93.29
STATE                  COMMIT
MIXED                  NO
ACTION
TRAN_COMMENT           Sales/New Order/Trans_type 10B
FAIL_TIME              31-MAY-91
FORCE_TIME
RETRY_TIME             31-MAY-91
OS_USER                SWILLIAMS
OS_TERMINAL            TWA139:
HOST                   SYSTEM1
DB_USER                SWILLIAMS
COMMIT#                129314

この時点で、トランザクションを解決しているノードが見つかりました。ビューが示しているように、このノードではコミットが完了しており、コミットID番号が割り当てられています。

STATE                  COMMIT
COMMIT#                129314

したがって、自分のローカル・データベースでインダウト・トランザクションを強制的にコミットできます。この調査結果を他の管理者に伝えれば、他の場所での解決にも役立つ可能性があります。

手順5: インダウト・トランザクションのコミット

salesデータベースの管理者と連絡を取り、グローバルIDを使用してインダウト・トランザクションを手動でコミットしてもらうように依頼します。

SQL> CONNECT SYS@sales.acme.com AS SYSDBA
SQL> COMMIT FORCE 'SALES.ACME.COM.55d1c563.1.93.29';

同時に、warehouseデータベースの管理者として、グローバルIDを使用してインダウト・トランザクションを手動でコミットします。

SQL> CONNECT SYS@warehouse.acme.com AS SYSDBA
SQL> COMMIT FORCE 'SALES.ACME.COM.55d1c563.1.93.29';

手順6: DBA_2PC_PENDINGを使用したMIXED結果のチェック

トランザクションを手動で強制的にコミットまたはロールバックした後も、ペンディング・トランザクション表の対応する行はそのまま残っています。トランザクションの状態は、トランザクションをどのように強制完了したかに応じて変わります。

Oracle Databaseには、必ずペンディング・トランザクション表があります。これは、2フェーズ・コミットの各フェーズの進行に従って分散トランザクションに関する情報を格納する特別な表です。データベースのペンディング・トランザクション表は、DBA_2PC_PENDINGデータ・ディクショナリ・ビューを介して問い合せることができます(詳細は表33-1を参照)。

また、ペンディング・トランザクション表で特に重要なものとして、DBA_2PC_PENDING.MIXEDに示されるMIXED結果フラグがあります。ペンディング・トランザクションを強制的にコミットまたはロールバックする場合は、選択を誤る可能性があります。たとえば、ローカル管理者がトランザクションをロールバックしたにもかからわず、他のノードではそのトランザクションをコミットしてしまうといったことが考えられます。このような誤った判断は自動的に検出され、対応するペンディング・トランザクションのレコードに損傷フラグが設定されます(MIXED=yes)。

RECOバックグラウンド・プロセスは、ペンディング・トランザクション表の情報を使用して、インダウト・トランザクションの状態を最終決定します。また、管理者がペンディング・トランザクション表の情報を使用して、保留中の分散トランザクションの自動リカバリ手順を手動で上書きすることもできます。

RECOによって自動的に解決されたトランザクションは、すべてペンディング・トランザクション表から削除されます。また、管理者によって正しく解決されたインダウト・トランザクションに関する情報も、RECOが通信を再確立したときにチェックされて、すべてペンディング・トランザクション表から自動的に削除されます。ただし、管理者が解決したことによってノード間にまたがってMIXEDの結果が生じた行は、DBMS_TRANSACTIONS.PURGE_MIXEDを使用して手動で削除しないかぎり、関係しているすべてのノードのペンディング・トランザクション表にそのまま残ります。

ロックによるデータ・アクセスの障害

SQL文を発行すると、データベースは文を正常に実行するために必要なリソースのロックを試みます。しかし、要求されたデータが、コミットされていない他のトランザクションの文によって現在保持されていて、長時間ロックされたままになっていると、タイムアウトが発生します。

データ・アクセスの障害に関しては、次の事例について考慮してください。

トランザクションのタイムアウト

リモート・データベースのロックを必要とするDML文は、要求したデータのロックを別のトランザクションが所有している場合にブロックされる可能性があります。このようなロックによってSQL文の要求がブロックされ続けると、次の一連のイベントが発生します。

  1. タイムアウトが発生します。

  2. データベースは文をロールバックします。

  3. データベースは次のエラー・メッセージをユーザーに返します。

    ORA-02049: タイムアウト: 分散トランザクションがロックを待機しています。
    
    

トランザクションによってデータは変更されていないので、タイムアウトの結果として必要な処理はありません。アプリケーションでは、デッドロックが発生したものとして処理を継続してください。文を実行したユーザーは、後で同じ文の再実行を試みることができます。それでもロックが続く場合には、ユーザーは管理者に連絡して問題を報告してください。

インダウト・トランザクションによるロック

ローカル・データベースのロックを必要とする問合せまたはDML文は、インダウト分散トランザクションによるリソースのロックのために無期限にブロックされる可能性があります。この場合、データベースは次のエラー・メッセージを発行します。

ORA-01591: インダウト分散トランザクションidentifierがロックを保持しています。

この場合、データベースはSQL文をただちにロールバックします。文を実行したユーザーは、後で同じ文の再実行を試みることができます。それでもロックが続く場合には、ユーザーは管理者に連絡して問題を報告してください。このとき、インダウト分散トランザクションのIDも併せて報告してください。

2フェーズ・コミットの重要な部分の処理中に障害が発生する確率は低いため、このような状況が起こる可能性はほとんどありません。仮にこのような障害が発生した場合でも、ネットワーク障害やシステム障害から迅速にリカバリできれば、手動で介入しなくても問題は自動的に解決されます。したがって、この種の問題は、ユーザーやDBAに検出される前に解決されるのが普通です。

分散トランザクション障害のシミュレーション

分散トランザクションの障害は、次のような理由で強制的に発生させることができます。

ここでは、使用可能な機能とその操作に必要な手順を説明します。

分散トランザクションの強制障害

COMMIT文のCOMMENTパラメータには、コメントを挿入できます。分散トランザクションの2フェーズ・コミットのフェーズ時に意図して障害を発生させるには、COMMENTパラメータに、次のコメントを挿入します。

COMMIT COMMENT 'ORA-2PC-CRASH-TEST-n';

コメント内のnには、次の整数のいずれかが入ります。

n  影響 

収集後コミット・ポイントをクラッシュ 

収集後コミット・ポイント・サイト以外をクラッシュ 

準備前にクラッシュ(コミット・ポイント・サイト以外) 

準備後にクラッシュ(コミット・ポイント・サイト以外) 

コミット前にコミット・ポイント・サイトをクラッシュ 

コミット後にコミット・ポイント・サイトをクラッシュ 

コミット前にコミット・ポイント・サイト以外をクラッシュ 

コミット後にコミット・ポイント・サイト以外をクラッシュ 

情報消去前にコミット・ポイント・サイトをクラッシュ 

10 

情報消去前にコミット・ポイント・サイト以外をクラッシュ 

たとえば、ローカルのコミット・ポイント強度がリモートのコミット・ポイント強度よりも高く、双方のノードが更新されている場合、次の文では、次のメッセージが返されます。

COMMIT COMMENT 'ORA-2PC-CRASH-TEST-7';

ORA-02054: トランザクション1.93.29はインダウトです。
ORA-02059: コミット・コメントにORA-2PC-CRASH-TEST-7が含まれています。

この時点で、インダウト分散トランザクションがDBA_2PC_PENDINGビューに表示されます。対応している場合は、RECOがそのトランザクションを自動的に解決します。

RECOの有効化と無効化

Oracle DatabaseインスタンスのRECOバックグラウンド・プロセスは、分散トランザクションに伴う障害を自動的に解決します。ノードのRECOバックグラウンド・プロセスは、時間間隔を指数関数的に広げながら、インダウト分散トランザクションのローカル部分のリカバリを試みます。

RECOは、障害を起こしたトランザクションに関係している他のノードに対して、既存の接続を使用するか、または新しい接続を確立できます。接続が確立されると、RECOはすべてのインダウト・トランザクションを自動的に解決します。各データベースのペンディング・トランザクション表内にインダウト・トランザクションに対応している行があれば、自動的に削除されます。

ENABLE/DISABLE DISTRIBUTED RECOVERYオプションを指定してALTER SYSTEM文を使用すると、RECOを使用可能または使用禁止にできます。たとえば、RECOを一時的に使用禁止にして2フェーズ・コミットの障害を強制的に発生させ、インダウト・トランザクションを手動で解決できます。

次の文は、RECOを使用禁止にします。

ALTER SYSTEM DISABLE DISTRIBUTED RECOVERY;

一方、次の文はRECOを使用可能にし、インダウト・トランザクションが自動的に解決されるようにします。

ALTER SYSTEM ENABLE DISTRIBUTED RECOVERY;


注意:

シングル・プロセス・インスタンス(MS-DOSが稼働しているPCなど)では、インスタンス以外のバックグラウンド・プロセスは稼働しておらず、したがってRECOプロセスはありません。そのため、分散システムに参加するシングル・プロセス・インスタンスを起動したときは、前述の文を使用して手動で分散リカバリを使用可能にする必要があります。  


読込み一貫性の管理

Oracle Databaseの分散読込み一貫性の実装には、重要な制限事項があります。この問題は、各システムが独自のSCNを持っていることに起因します。SCNは、データベースの内部タイムスタンプとして表示できます。Oracle Databaseサーバーは、SCNを使用して、問合せにどのバージョンのデータを返せばよいかを判断します。

分散トランザクションのSCNは、リモートSQL文の最後と、各トランザクションの最初および最後で同期化されます。2つのノード間の通信量が多く、特に分散更新がある場合には、この同期化が頻繁に実行されます。しかし、分散システムのSCNの絶対的な同期を保つための実用的な手段は存在しません。つまり、あるノードのSCNが別のノードのSCNと比べて幾分古くなるというような状況が常に存在します。

このようなSCNの食い違いから、実行した問合せがわずかに古いスナップショットを使用する可能性があります。その問合せ結果には、リモート・データベースに対する最新の変更が含まれていません。そのため、問合せを実行したときに、読込み一貫性に従ってデータが取得されているにもかからわず、そのデータが古い場合があります。そのような問合せによって取得したデータは、すべて古いSCNに基づいています。したがって、ローカルに実行した更新トランザクションによってリモート・ノードの2つの表が更新された場合、次回のリモート・アクセスで両方の表から選択したデータには、更新前のデータが含まれることになります。

SCNが食い違っているために起こりうる結果の1つとして、SELECT文が2つ連続している場合に、それら2つの文の間でDMLをまったく実行していなくても各文で異なるデータが取得されることがあります。たとえば、UPDATE文を発行して、リモート・データベースで更新をコミットしたとします。このリモート表に基づくビューに対してSELECT文を発行すると、ビューには更新された行が表示されません。次にSELECT文を発行するときは、更新された行が表示されます。

次の手法を使用すると、問合せの直前に2つのマシンのSCNが必ず同期化されます。


戻る 次へ
Oracle
Copyright © 2001, 2008, Oracle Corporation.
All Rights Reserved.
目次
目次
索引
索引