透過的アプリケーション・フェイルオーバー
Oracle透過的アプリケーション・フェイルオーバー(TAF)は、クライアント側の高可用性機能です。これにより、接続されたプライマリ・インスタンスに障害が発生した場合や停止した場合に、クライアントがセカンダリ・データベース・インスタンスに自動的に再接続できるようになります。
TAFを使用するために新しいフェイルオーバー・コードは必要ありません。名前が示すように、この機能は透過的です。つまり、TAFが有効になって構成されている場合、ODP.NETおよびOracleデータベースはインスタンス障害検出および接続の再確立プロセスを管理します。
ODP.NET Core、管理対象および管理対象外のプロバイダ・タイプはすべてTAFをサポートしています。ODP.NET Coreおよび管理対象のサポートは、ODP.NET 23.3.3で開始されました。各プロバイダ・タイプでサポートされるTAF機能には違いがあります。
TAFは、データベースまたはクライアント側で構成できます。クライアント側では、Oracle接続記述子またはODP.NET APIを使用してTAF設定を行うことができます。
TAFは、アクティブなデータベース接続に関連する次の要素の、いくつかまたはすべてを自動的にリストアします。他の要素でリカバリが必要な場合は、ODP.NET TAFコールバック内など、アプリケーション・コードに追加する必要があります。ODP.NET TAFリカバリ機能の詳細は、次のとおりです:
-
データベース接続
TAFは、フェイルオーバー用に指定された同じ接続文字列または代替接続文字列を使用して、ODP.NET接続を自動的に再確立します。
-
ユーザー・データベース・セッション
TAFでは、最初に使用したものと同じログイン資格証明を使用してユーザーが自動的にログインされます。複数のユーザーが同じ接続を使用する場合、これらのユーザーがデータベース・コマンドを処理しようとすると、TAFはこれらのユーザーを自動的にログインします。残念ながら、TAFは他のセッション・プロパティを自動的にはリストアできませんが、これらのプロパティはコールバック関数を呼び出すことでリストアできます。
-
完了コマンド
接続失敗の時点でコマンドが完了し、データベース状態を変更した場合、TAFは再接続時にコマンドを再送しません。TAFが再接続し、別のコマンドによってデータベースが変更された可能性がある場合は、TAFによってアプリケーションにエラー・メッセージが表示されます。このTAF機能は、管理対象外のODP.NETから使用できますが、管理対象ドライバもコア・ドライバも使用できません。
-
結果フェッチ用のカーソルのオープン
TAFでは、フェイルオーバー前にカーソルから行のフェッチを開始していたアプリケーションが、リカバリ後も行のフェッチを続行できます。これは選択フェイルオーバーと呼ばれています。同じスナップショットを使用して
SELECT文を再実行し、すでにフェッチした行を廃棄し、最初にフェッチしなかった行を取得します。TAFでは、廃棄した行が最初に戻された行であることを確認するか、またはエラー・メッセージを返します。このTAF機能は、管理対象外のODP.NETから使用できますが、管理対象ドライバもコア・ドライバも使用できません。 -
アクティブ・トランザクション
アクティブ・トランザクションはすべて、障害発生時にロールバックされます。TAFはフェイルオーバー後にアクティブ・トランザクションを保持できません。このため、アプリケーションは、
ROLLBACKコマンドが発行されるまでエラー・メッセージを受け取ることになります。 -
サーバー側プログラム変数
PL/SQLパッケージの状態などのサーバー側プログラム変数は、障害発生時に失われます。TAFは回復できません。これらは、フェイルオーバー・コールバックからコールすることによって再初期化できます。
TAFは、TNS接続記述子のFAILOVER_MODE属性を使用してクライアント側で構成できます。
表3-11 ODP.NET TAFフェイルオーバー・モードのサポート
| TAFフェイルオーバー・モード | ODP.NET Coreのサポート | 管理対象ODP.NETのサポート | 管理対象外ODP.NETのサポート | 説明 |
|---|---|---|---|---|
|
セッション・フェイルオーバー |
Y |
Y |
Y |
失われた接続とセッションを再作成します |
|
フェイルオーバーの選択 |
N |
N |
Y |
進行中の問合せのリプレイ |
表3-12 ODP.NET TAFフェイルオーバー・メソッドのサポート
| TAFフェイルオーバー・メソッド | ODP.NET Coreのサポート | 管理対象ODP.NETのサポート | 管理対象外ODP.NETのサポート | 説明 |
|---|---|---|---|---|
|
基本 |
Y |
Y |
Y |
フェイルオーバー時に接続を確立します。このオプションでは、フェイルオーバーまでバックアップ・データベース・サーバーでの作業はほとんど不要です。 |
|
事前接続 |
N |
N |
Y |
バックアップ・インスタンスで接続を事前に確立します。これにより、フェイルオーバーは高速になりますが、バックアップ・インスタンスはプライマリ・インスタンスからのすべての接続をサポートする必要があります。 |
ノート:
管理対象ODP.NETおよびODP.NET Coreは、BACKUPおよびTRANSACTION TAFパラメータをサポートしていません。BACKUPは、フェイルオーバー・ノードを指定します。TRANSACTIONを使用すると、リカバリ可能なエラーの後、データベースで現行のトランザクションが完了するようになります。
TAF通知
フェイルオーバーによる遅延を考慮して、アプリケーションではTAFコールバックによる通知を必要とします。ODP.NETは、OracleConnectionオブジェクトのFailoverイベントによるTAFコールバック機能をサポートしています。これにより、フェイルオーバーが発生したときは常にアプリケーションに通知されます。TAFコールバックを受信するには、Failoverイベントにイベント・ハンドラ関数を登録する必要があります。
フェイルオーバーが発生した場合
フェイルオーバーが発生すると、Failoverイベントが発生し、別のOracleインスタンスに接続を再確立する過程で、イベント・ハンドラが複数回起動されます。
イベント・ハンドラの最初のコールは、Oracleデータベースがインスタンス接続の損失を最初に検出したときに行われます。これにより、アプリケーションはフェイルオーバーの次の遅延に応じて動作します。
フェイルオーバーが成功した場合、接続が再確立されて使用可能になったときにFailoverイベントが発生します。この時点で、アプリケーションはOracleGlobalizationセッション設定を再同期化して、フェイルオーバーが発生したことをアプリケーション・ユーザーに通知できます。FailoverEvent.Beginイベントの直後には、大きいデータベース操作が発生しません。SQLと主なデータベース操作は、FailoverEvent.Endイベントまで待つようにしてください。FailoverEvent.Beginは主として、フェイルオーバーを拒否するか、またはフェイルオーバーをトレースするために使用されます。FailoverEvent.Beginは、フェイルオーバーが進行中であり、完了を待ってから続行するようエンド・ユーザーに告知するなど、データベース以外のアプリケーション操作にも使用されます。トランザクションは、フォルト・チケットの発行や監査など、FailoverEvent.Endコールバック・フェーズで使用できます。これらのトランザクションは、コールバックが完了する前にコミットする必要があります。
フェイルオーバーが失敗した場合、フェイルオーバーが発生しなかったことをアプリケーションに通知するために、Failoverイベントが発生します。
アプリケーションは、イベント・ハンドラに渡されるOracleFailoverEventArgsオブジェクトをチェックすることで、フェイルオーバーが成功したかどうかを判断できます。
フェイルオーバーのイベント・ハンドラの登録
次のコード例は、OnFailoverと呼ばれるイベント・ハンドラ・メソッドを登録します。
// C#
using System;
using Oracle.DataAccess.Client;
class TAFCallBackSample
{
public static FailoverReturnCode OnFailover(object sender,
OracleFailoverEventArgs eventArgs)
{
switch (eventArgs.FailoverEvent)
{
case FailoverEvent.Begin :
Console.WriteLine(
" \nFailover Begin - Failing Over ... Please standby \n");
Console.WriteLine(
" Failover type was found to be " + eventArgs.FailoverType);
break;
case FailoverEvent.Abort :
Console.WriteLine(" Failover aborted. Failover will not take place.\n");
break;
case FailoverEvent.End :
Console.WriteLine(" Failover ended ...resuming services\n");
break;
case FailoverEvent.Reauth :
Console.WriteLine(" Failed over user. Resuming services\n");
break;
case FailoverEvent.Error :
Console.WriteLine(" Failover error gotten. Sleeping...\n");
return FailoverReturnCode.Retry;
default :
Console.WriteLine("Bad Failover Event: %d.\n", eventArgs.FailoverEvent);
break;
}
return FailoverReturnCode.Success;
} /* OnFailover */
static void Main()
{
OracleConnection con = new OracleConnection();
con.ConnectionString = "User Id=scott;Password=tiger;Data Source=oracle;";
con.Open();
con.Failover += new OracleFailoverEventHandler(OnFailover);
Console.WriteLine("Event Handler is successfully registered");
// Close and Dispose OracleConnection object
con.Close();
con.Dispose();
}
}
Failoverイベントは、1つのイベント・ハンドラのみを起動します。Failoverイベントに複数のFailoverイベント・ハンドラが登録されていても、最後に登録されたイベント・ハンドラのみが起動されます。
ノート:
フェイルオーバーが有効な環境では、分散トランザクションはサポートされません。