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

前
 
次
 

15 データベースのフェイルオーバーおよびリカバリの管理

この章の説明は、アクティブ・スタンバイ・ペアを含むすべてのレプリケーション・スキームに適用されます。ただし、アクティブ・スタンバイ・ペアの監視には、Oracle Clusterwareと統合されたTimesTenが最適です。第8章「Oracle Clusterwareを使用したアクティブ・スタンバイ・ペアの管理」を参照してください。

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

データベースのフェイルオーバーおよびリカバリの概要

高可用性システムの設計での基本的な要素は、障害からすぐにリカバリできる機能です。障害は、システムの障害やネットワークの障害など、ハードウェアの問題に関連している場合があります。ソフトウェアの障害には、オペレーティング・システムの障害、アプリケーションの障害、データベースの障害およびオペレータのエラーが含まれます。

レプリケート・システムでは、クラスタ・マネージャまたはカスタム・ソフトウェアを使用してこのような障害を検出し、マスター・データベースに関連する障害が発生した場合は、ユーザー負荷をいずれかのサブスクライバにリダイレクトする必要があります。ここでは、アプリケーションまたはクラスタ・マネージャで障害のリカバリに使用できるTimesTenメカニズムについて説明します。

レプリケーション・スキームがRETURN TWOSAFEを使用するように構成されていないかぎり、TimesTenでは、元のトランザクションがマスター・データベースにコミットした後にのみ、更新がレプリケートされます。サブスクライバ・データベースが稼働できない場合、またはサブスクライバ・データベースへの通信で障害が発生した場合でも、マスターでの更新は妨げられません。サブスクライバ・システムの停止中、サブスクライバへの更新はTimesTenトランザクション・ログに保存されます。


注意:

この章の手順を実行するには、ADMIN権限が必要です。

一般的なフェイルオーバーおよびリカバリの手順

フェイルオーバーおよびリカバリを管理するための手順は、主に次の内容に依存します。

  • レプリケーション・スキーム

  • 障害がマスターまたはサブスクライバのデータベースのいずれで発生したか。

  • 問題が解決され、データベースを再接続する前に、マスターのトランザクション・ログのしきい値を超えてしまったかどうか。

サブスクライバの障害

デフォルトの非同期のレプリケーション・スキームでは、サブスクライバ・データベースが稼働できない場合、またはサブスクライバ・データベースへの通信で障害が発生した場合でも、マスターでの更新は妨げられないため、クラスタ・マネージャですぐに処理を行う必要はありません。


注意:

障害が発生したサブスクライバがRETURNサービスを使用するように構成されている場合は、まず、RETURNサービス・ブロッキングを無効にする必要があります(「RETURNサービス・タイムアウト・エラーおよびレプリケーションの状態変化の管理」を参照)。

サブスクライバ・システムの停止中、サブスクライバへの更新はマスターのトランザクション・ログに保存されます。マスターがFAILTHRESHOLDに達する前にサブスクライバ・エージェントがマスターとの通信を再開した場合、ログに保存されていた更新はサブスクライバに自動的に送信されるため、これ以上の処理は必要ありません。マスター・データベースのFAILTHRESHOLD値の設定方法の詳細は、「トランザクション・ログ障害しきい値の設定」を参照してください。

FAILTHRESHOLDを超えた場合、マスターはサブスクライバをfailed状態に設定するため、このサブスクライバは、「障害が発生したデータベースのリカバリ」の説明に従ってリカバリする必要があります。障害が発生したサブスクライバに接続中のアプリケーションは、データベースがレプリケーション・ピアによってfailedとマークされたことを示すtt_ErrReplicationInvalid(8025)警告を受信します。

アプリケーションでは、ODBCのSQLGetInfo関数を使用して、接続中のサブスクライバ・データベースがfailed状態に設定されているかどうかを確認できます。SQLGetInfo関数には、TimesTen固有の情報タイプTT_REPLICATION_INVALIDが含まれていて、データベースで障害が発生した場合は32ビットの整数値1、障害が発生しなかった場合は0(ゼロ)を返します。


注意:

情報タイプTT_REPLICATION_INVALIDはTimesTenに固有であるため、これを使用するすべてのアプリケーションでは、ODBCの他のincludeファイルに加えて、timesten.hファイルをインクルードする必要があります。

ただし、各データベースがマスターとサブスクライバの両方として動作する双方向のレプリケーション・スキームを使用している場合に、一方のサブスクライバが失敗すると、エラーが発生します。たとえば、双方向のレプリケーション・スキームのマスターおよびサブスクライバが次のように定義されているとします。

CREATE REPLICATION r1
ELEMENT elem_accounts_1 TABLE ttuser.accounts
  MASTER westds ON "westcoast"
  SUBSCRIBER eastds ON "eastcoast"
ELEMENT elem_accounts_2 TABLE ttuser.accounts
  MASTER eastds ON "eastcoast"
  SUBSCRIBER westds ON "westcoast";
  • eastdsサブスクライバが失敗すると、westdsマスターは失敗を受信するため、このサブスクライバへの更新の蓄積を停止します。

  • eastdsサブスクライバが失敗すると、eastdsのレプリケーション・エージェントは停止します。ただし、eastdsマスターはレプリケーション・エージェントが停止されていることを認識せず、更新の蓄積を続行し、westdsのサブスクライバに伝播します。レプリケーション・エージェント(レコードをサブスクライバに伝播し、FAILTHRESHOLDを監視する)が停止しているため、これらの更新は、定義済のFAILTHRESHOLDを超えて蓄積され続けます。

双方向のレプリケーション・スキームを使用している場合に、失敗したデータベースでTT_REPLICATION_INVALIDが1に設定されている場合は、次の手順を実行します。

  1. 失敗したデータベースを破棄します(この例ではeastdsデータベース)。

  2. 双方向のレプリケーション・スキームのもう一方のマスターからttRepAdmin -duplicate操作を実行して、失敗したデータベースを再作成します(この例ではwestdsのマスター)。

例15-1 データベースがfailed状態に設定されているかどうかの確認

hdbcハンドルで識別されたデータベースがfailed状態に設定されているかどうかを確認します。

SQLINTEGER retStatus;

SQLGetInfo(hdbc, TT_REPLICATION_INVALID,
          (PTR)&retStatus, NULL, NULL);

マスターの障害

クラスタ・マネージャは、障害がマスター・データベースに関連している場合により中心的な役割を果たします。マスター・データベースで障害が発生すると、クラスタ・マネージャはこの障害を検出し、影響を受けなかったいずれかのデータベースにユーザー・ロードをリダイレクトする必要があります。影響を受けなかったこのサブスクライバが新しいマスターとなり、トランザクションを処理して、障害を受けなかった他のサブスクライバ・データベースにレプリケートします。障害が発生したマスターと障害の影響を受けなかったサブスクライバを双方向方式で構成していた場合、障害が発生したマスターからサブスクライバへのユーザー・ロードの転送でレプリケーション・スキームを変更する必要はありません。ただし、単方向レプリケーションまたはプロパゲータが関連するスキームなどの複雑なスキームを使用している場合は、1つ以上のALTER REPLICATION文を発行して、障害の影響を受けなかったサブスクライバを新しいマスターとしてスキームに再構成する必要があります。詳細は、「クラシック・レプリケーション・スキームでのマスター・データベースの交換」を参照してください。

問題の解決時に、「障害が発生したマスター・データベースの自動キャッチアップ」で説明されている双方向構成またはアクティブ・スタンバイ・ペアを使用していない場合は、「障害が発生したデータベースのリカバリ」の説明に従ってマスター・データベースをリカバリする必要があります。

データベースがオンラインに戻った後、クラスタ・マネージャは、ユーザー・ロードを元のマスターに戻すか、または元のマスターを代理マスターのサブスクライバとして再設定することもできます。

障害が発生したマスター・データベースの自動キャッチアップ

マスター・キャッチアップ機能は、ttRepAdmin -duplicate処理(「障害が発生したデータベースのリカバリ」を参照)を実行する必要がなく、サブスクライバ・データベースから障害のあったマスター・データベースを自動的にリストアします。

マスター・キャッチアップ機能は、構成の必要はありませんが、次のタイプの構成でのみ使用できます。

  • 1つのサブスクライバに双方向方式でレプリケートされる1つのマスター

  • RETURN TWOSAFEを使用して構成されているアクティブ・スタンバイ・ペア

アクティブ・スタンバイ・ペアではないレプリケーション・スキームの場合、次の要件を満たす必要があります。

  • ELEMENTタイプがDATASTOREである。

  • TRANSMIT NONDURABLEまたはRETURN TWOSAFEが有効である必要がある。

  • すべてのレプリケート対象のトランザクションが非永続的にコミットされる必要がある。ローカル・データベースでコミットされる前にリモート・データベースに送信される必要があります。たとえば、レプリケーション・スキームがRETURN TWOSAFE BY REQUESTで構成され、最初にRETURN TWOSAFEを有効にせずにトランザクションがコミットされた場合、マスターに障害が発生した後にマスター・キャッチアップが発生しないことがあります。

クラッシュまたは無効化の後にマスター・レプリケーション・エージェントを再起動すると、マスターで消失したトランザクションがサブスクライバからマスターに(アクティブ・スタンバイ・ペアの場合はスタンバイからアクティブに)自動的にレプリケートされます。マスター・データベースがサブスクライバと完全に同等となるまで、マスター・データベースに接続することはできません。キャッチアップ・フェーズでデータベースへの接続を試行したアプリケーションは、キャッチアップ中であることを示すエラーを受信します。例外は、DSNにForceConnect初期接続属性が設定されているデータベースに接続する場合のみです。

キャッチアップ・フェーズが終了すると、アプリケーションでデータベースに接続できます。キャッチアップ・フェーズの終了は、システム・ログへのSNMPトラップおよびメッセージで示されます。

キャッチアップ・プロセスでいずれかのデータベースが無効にされたか、またはクラッシュした場合、キャッチアップ・フェーズは、データベースが再起動されると再開します。

次のような状況では、マスター・キャッチアップは失敗する場合があります。

  • 障害が発生したデータベースが長時間オフラインになり、サブスクライバ・データベース(アクティブ・スタンバイ・ペアのスタンバイ・データベース)で障害しきい値を超えた。

  • 障害発生時に、アクティブ・スタンバイ・ペアのアクティブ・データベースで動的なロード処理が実行されていた。RETURN TWOSAFEは、アクティブ・データベースに対して有効になっていても、動的なロード処理では有効になりません。データベースの障害によって動的なロードのトランザクションがトラップされ、RETURN TWOSAFEで障害が発生します。

アクティブ・スタンバイ・ペアにマスター・キャッチアップが必要な場合

TimesTenエラー8110(Connection not permitted. This store requires Master Catchup.)は、スタンバイ・データベースがアクティブ・データベースより先行し、レプリケーションが再開するにはマスター・キャッチアップが必要であることを示します。

アクティブ・スタンバイ・ペアでマスター・キャッチアップを使用している場合、スタンバイ・データベースがフェイルオーバーにより新しいアクティブ・データベースになる必要があります。古いアクティブ・データベースのリカバリができると、そのデータベースが新しいスタンバイ・データベースになります。リカバリができない場合は、古いアクティブ・データベースを破棄し、新しいアクティブ・データベースを複製することによって新しいスタンバイ・データベースを作成する必要があります。RETURN TWOSAFEが構成されている(マスター・キャッチアップに必要)場合の、アクティブ・データベースの障害からのリカバリの詳細は、「レプリケーションがRETURN TWOSAFEの場合」を参照してください。

RETURN TWOSAFEを使用して構成されているアクティブ・スタンバイ・ペアでは、トラップされたトランザクションが含まれる可能性があります。フェイルオーバー後新しいアクティブ・データベースに存在しないトランザクションが新しいスタンバイ・データベースに存在する場合に、トラップされたトランザクションが発生します。エラー16227(Standby store has replicated transactions not present on the active)はトラップされたトランザクションを示す一例です。トラップされたトランザクションの数は、手動リカバリ処理中に各データベースでレプリケート表のレコード数をチェックすることによって確認できます。たとえば、次のように文を入力します。

SELECT COUNT(*) FROM reptable;

トラップされたトランザクションがある場合、次のタスクを実行してリカバリを行います。

  1. ttRepStateSet組込みプロシージャを使用して、スタンバイ・データベースの状態を'ACTIVE'に変更します。

  2. 古いアクティブ・データベースを破棄します。

  3. ttRepAdmin -duplicateを使用して、すべてのトランザクションを含む新しいアクティブ・データベースから新しいスタンバイ・データベースを作成します。「データベースの複製」を参照してください。

双方向の分散ワークロード・スキームの障害

それぞれがマスターおよびサブスクライバの両方として機能する、双方向にレプリケートされた複数のデータベースにワークロードを分散できます。マスター/サブスクライバ・データベースをリカバリする場合、レプリケーションの再起動時に、障害が発生したデータベースのログに問題が示される可能性があります。「双方向の分散ワークロード・スキーム」を参照してください。

分散ワークロード・スキームのデータベースで障害が発生し、影響を受けなかったデータベースに作業を切り替えた場合、影響を受けなかったデータベースには障害が発生したデータベースより新しい情報が反映されます。影響を受けなかったデータベースでログ障害しきい値に達する前に、障害が発生したシステムでレプリケーションが再起動された場合、両方のデータベースは、トランザクション・ログの内容を使用して互いの更新を試行します。この場合、障害が発生したデータベースのトランザクション・ログの古い更新が、影響を受けなかったシステムの新しいデータを上書きする可能性があります。

このような状況でリカバリするには、次の2つの方法があります。

  • タイムスタンプによる競合解消ルール(第13章「レプリケーション競合の解消」を参照)がアプリケーションの一貫性の保証に十分な場合は、障害が発生したシステムを再起動し、障害が発生したデータベースの更新を影響を受けなかったデータベースに伝播することができます。この競合解消ルールによって、新しい更新が上書きされなくなります。

  • 「障害が発生したデータベースのリカバリ」の説明に従って、障害が発生したデータベースを再作成します。データベースを再作成する必要がある場合、障害が発生したデータベースのログに保存されていた更新のうち、障害が発生していないデータベースで受信していない更新を識別またはリストアすることはできません。障害が発生していないデータベースが複数ある場合は、どのデータベースを使用して障害が発生したデータベースを再作成するかを選択する必要があります。障害が発生したデータベースを再作成する時点で、選択したデータベースが、障害が発生していない他のデータベースからの更新のすべてを受信していないこともあります。この場合、データベース間で相違が発生します。このような状況を避ける唯一の方法として、選択したデータベースから、障害が発生していない他のデータベースすべてを再作成する方法があります。

ネットワークの障害

一時的なネットワークの障害が発生した場合、レプリケーションを続行するために特定の処理を実行する必要はありません。通信中だったレプリケーション・エージェントは、数秒ごとに再接続を試行します。マスター・データベースがログ領域を使い果たす前にエージェントが再接続すると、レプリケーション・プロトコルによって、レプリケーション更新の見落しも重複もないことが確認されます。ネットワークを長期間使用できず、マスター・ログの障害しきい値を超えた場合は、「障害が発生したデータベースのリカバリ」の説明に従って、サブスクライバをリカバリする必要があります。

順序に関連した障害

キューされたログを再生してレプリケーションをリカバリできる場合、ネットワーク・リンクで障害が発生した後に処理を行う必要はありません。

ただし、障害が発生したホストが長時間にわたって停止した場合は、順序は障害のリカバリ中にロールバックされないため、ttRepAdmin -duplicateコマンドを使用して、障害の影響を受けなかったホストから障害が発生したホストのデータベースにトランザクションを再移入する必要があります。この場合、ttRepAdmin -duplicateコマンドによって、データベース間の順序定義のコピーが実行されます。

障害が発生したデータベースのリカバリ

データベースが双方向レプリケーション・スキームで構成されている場合、障害が発生したマスター・データベースはサブスクライバから自動的に最新の状態にされます。「障害が発生したマスター・データベースの自動キャッチアップ」を参照してください。また、自動キャッチアップがアクティブ・スタンバイ・ペアのマスター・データベースのリカバリに適用されます。

再起動したデータベースをマスターのトランザクション・ログからリカバリして、レプリケーション・システムの他のデータベースとの一貫性を保つことができない場合、そのレプリケーション・ピアの1つからデータベースを再作成する必要があります。コマンドライン・ユーティリティまたはTimesTenユーティリティのC関数を使用します。「コマンドラインからの障害が発生したデータベースのリカバリ」および「Cプログラムからの障害が発生したデータベースのリカバリ」を参照してください。


注意:

障害が発生したデータベースのDSNを再作成する必要はありません。

サブスクライバで障害が発生した場合、RETURNサービスで構成された表に対するマスター・データベースでのコミットは、RETURNサービス・タイムアウト時間に達するまで実行されません。これを回避するには、RETURNサービスの障害およびリカバリ・ポリシーをレプリケーション・スキームに設定します(「RETURNサービス・タイムアウト・エラーおよびレプリケーションの状態変化の管理」を参照)。RETURN RECEIPTサービスを使用している場合は、ALTER REPLICATIONを使用してNO RETURN属性を設定し、サブスクライバがリストアされ、最新情報を反映するまでRETURN RECEIPTを無効にすることもできます。反映した時点で、別のALTER REPLICATION文を実行してRETURN RECEIPTを再設定できます。

コマンドラインからの障害が発生したデータベースのリカバリ

データベースを完全にレプリケートする場合は、ttDestroyユーティリティを使用して、障害が発生したデータベースをメモリーから削除し、ttRepAdmin -duplicateを使用して、影響を受けなかったデータベースから再作成することができます。データベースにキャッシュ・グループが含まれている場合は、ttRepAdmin-keepCGオプションも使用する必要があります。「データベースの複製」を参照してください。

例15-2 障害が発生したデータベースのリカバリ

障害が発生したデータベースsubscriberdsをホストsystem1のマスターmasterdsからリカバリするには、次のように入力します。

> ttdestroy /tmp/subscriberds

> ttrepadmin -dsn subscriberds -duplicate -from masterds -host "system1" -uid ttuser

ttuserのパスワードを入力するよう求められます。


注意:

ttRepAdmin -duplicateは、同一のTimesTenリリースおよびパッチ・リリース間でのみサポートされます。メジャーおよびマイナーのリリース番号が同じである必要があります。

ttRepAdmin -duplicateを使用してデータベースを再作成した後、データベースに最初に接続すると、データベースがメモリーにリロードされます。大容量のデータベースの複製時にパフォーマンスを向上させるには、ttRepAdmin -ramloadオプションを使用して複製処理後もデータベースをメモリー内に保持して、リロード・ステップを回避します。

例15-3 データベースのリカバリ時におけるデータベースのメモリー内への保持

障害のあったデータベースsubscriberdsをホストsystem1のマスターmasterdsからリカバリし、データベースをメモリー内に保持して、複製処理の後でレプリケーションを再起動するには、次のように入力します。

> ttdestroy /tmp/subscriberds

> ttrepadmin -dsn subscriberds -duplicate -ramload -from masterds -host "system1"
-uid ttuser -setmasterrepstart

ttuserのパスワードを入力するよう求められます。


注意:

ttRepAdmin -duplicate -ramLoadオプションを使用してデータベースを複製した後、データベースのRAMポリシーは、ttAdmin -ramPolicyまたはttRamPolicy関数で明示的に再設定されるまでmanualとなります。

Cプログラムからの障害が発生したデータベースのリカバリ

TimesTenユーティリティ・ライブラリで提供されるC関数を使用して、障害が発生したデータベースをプログラムでリカバリできます。

データベースを完全にレプリケートする場合は、ttDestroyDataStore関数を使用して、障害が発生したデータベースを削除し、ttRepDuplicateEx関数を使用して、影響を受けなかったデータベースから再作成することができます。

例15-4 障害が発生したデータベースのリカバリおよび起動

ホストsystem1のマスターmasterdsから、ホストsystem2の障害が発生したデータベースsubscriberdsをリカバリおよび起動するには、次のように入力します。

int          rc;
ttutilhandle utilhandle;
ttrepduplicateexarg arg;
memset( &arg, 0, sizeof( arg ) );
arg.size = sizeof( ttrepduplicateexarg );
arg.flags = tt_repdup_repstart | tt_repdup_ramload;
arg.uid=ttuser;
arg.pwd=ttuser;
arg.localhost = "system2";
rc = ttdestroydatastore( utilhandle, "subscriberds", 30 );
rc = ttrepduplicateex( utilhandle, "dsn=subscriberds",
                      "masterds", "system1", &arg );

この例では、ttDestroyDataStore処理のタイムアウト時間は30秒です。ttRepDuplicateEx関数の最後のパラメータは、次の2つのフラグを含む引数構造になっています。

  • 複製処理の完了後にsubscriberdsデータベースをstart状態に設定するTT_REPDUP_RESTART

  • RAMポリシーをmanualに設定してメモリーにデータベースを保持するTT_REPDUP_RAMLOAD


注意:

ttRepDuplicateExTT_REPDUP_RAMLOADフラグを使用すると、複製データベースのRAMポリシーは、ttRamPolicy関数またはttAdmin -ramPolicyで明示的に再設定されるまでmanualとなります。

TimesTen C言語ユーティリティ・ライブラリで提供される関数の完全なリストについては、『Oracle TimesTen In-Memory Database C開発者ガイド』のTimesTenユーティリティAPIに関する説明を参照してください。

非永続的データベースのリカバリ

双方向構成でTRANSMIT NONDURABLEオプションを指定してデータベースを構成する場合は、障害が発生したマスター・データベースをリカバリするために処理を行う必要はありません。「障害が発生したマスター・データベースの自動キャッチアップ」を参照してください。

他のタイプの構成では、TRANSMIT NONDURABLEオプションで構成されたマスター・データベースで障害が発生した場合、ttRepAdmin -duplicateまたはttRepDuplicateExを使用して、最新のサブスクライバ・データベースからマスター・データベースを再作成する必要があります。アプリケーションで最初に複製処理を行わずに、マスター・データベースに再接続しようとすると、レプリケーション・エージェントによってデータベースはリカバリされますが、複製処理を行うように忠告するエラーが返されます。このエラーが発生しないようにするには、アプリケーションでForceConnect初期接続属性を1に設定して再接続する必要があります。

障害リカバリ・スクリプトの作成

障害を検出した後、クラスタ・マネージャは、例15-5の擬似コードで示されたプロシージャを効果的に実行するスクリプトを実行する必要があります。

例15-5 障害リカバリ擬似コード

Detect problem {
       if (Master == unavailable) {
          FailedDataDatabase = Master
          FailedDSN = Master_DSN
          SurvivorDatabase = Subscriber
          switch users to SurvivorDatabase
      }
else {
          FailedDatabase = Subscriber
          FailedDSN = Subscriber_DSN
          SurvivorDatabase = Master
      }
}
Fix problem....
If (Problem resolved) {
       Get state for FailedDatabase
       if (state == "failed") {
         ttDestroy FailedDatabase
         ttRepAdmin -dsn FailedDSN -duplicate
                 -from SurvivorDatabase -host SurvivorHost
                 -setMasterRepStart
                 -uid ttuser
                 -pwd ttuser
      }
      else {
         ttAdmin -repStart FailedDSN
      }
      while (backlog != 0) {
         wait
      }
}

Switch users back to Master.

これは、マスターまたはサブスクライバのいずれかのデータベースに適用します。マスターで障害が発生すると、一部のトランザクションが失われる場合があります。