Share via


データベース ミラーリングの使用 (JDBC)

データベース ミラーリングは、主にデータベースの可用性とデータの冗長性を向上するためのソフトウェア ソリューションです。Microsoft SQL Server JDBC Driver は、データベース ミラーリングを暗黙的にサポートするため、データベース用に構成されていれば、開発者がコードを記述したり、その他の操作を行ったりする必要はありません。

データベース ミラーリングは、データベースごとに実装され、スタンバイ サーバー上に SQL Server 運用データベースのコピーを保持します。このサーバーは、データベース ミラーリング セッションの構成と状態によって、ホット スタンバイ サーバーまたはウォーム スタンバイ サーバーのいずれかになります。ホット スタンバイ サーバーは、コミットされたトランザクションを損失することなくラピッド フェールオーバーをサポートし、ウォーム スタンバイ サーバーは、サービス強制をサポートします (データ損失の可能性があります)。

運用データベースはプリンシパル データベースと呼ばれ、スタンバイ コピーはミラー データベースと呼ばれます。プリンシパル データベースとミラー データベースは、SQL Server の別々のインスタンス (サーバー インスタンス) 上に存在する必要があります。また、可能であれば、これらのデータベースは別々のコンピュータ上に配置してください。

プリンシパル サーバーと呼ばれる運用サーバー インスタンスは、ミラー サーバーと呼ばれるスタンバイ サーバー インスタンスと通信します。プリンシパル サーバーとミラー サーバーは、データベース ミラーリング セッション内でパートナーとして機能します。プリンシパル サーバーで障害が発生した場合、ミラー サーバーはフェールオーバーと呼ばれる処理を通じて、ミラー サーバーのデータベースをプリンシパル データベースにできます。たとえば、Partner_A と Partner_B は 2 つのパートナー サーバーで、最初はプリンシパル サーバーの Partner_A にプリンシパル データベース、ミラー サーバーの Partner_B にミラー データベースが存在するとします。Partner_A がオフラインになった場合は、Partner_B 上のデータベースをフェールオーバーして、現在のプリンシパル データベースにできます。Partner_A がミラーリング セッションに再び参加すると、Partner_A はミラー サーバーとなり、Partner_A のデータベースはミラー データベースとなります。

Partner_A サーバーが破損して修復不可能な場合は、Partner_C サーバーをオンラインにして、プリンシパル サーバーとなった Partner_B のミラー サーバーとして機能させることができます。ただし、このシナリオでは、データベース ミラーリング構成で使用される新しいサーバー名で接続文字列プロパティが更新されるように、クライアント アプリケーションにプログラミング ロジックを含める必要があります。含めない場合、サーバーへの接続に失敗する可能性があります。

代替のデータベース ミラーリング構成では、さまざまなレベルのパフォーマンスおよびデータ安全性が提供され、異なる形式のフェールオーバーがサポートされます。詳細については、SQL Server オンライン ブックの「データベース ミラーリングの概要」を参照してください。

プログラムに関する考慮事項

プリンシパル データベース サーバーで障害が発生すると、クライアント アプリケーションは API 呼び出しの応答としてエラーを受信します。これは、データベースへの接続が失われたことを示します。この問題が発生すると、データベースに対するコミットされていない変更はすべて失われ、現在のトランザクションはロールバックされます。このような場合、アプリケーションでは接続を閉じて (または、データ ソース オブジェクトを解放して) から、再び開く必要があります。接続時に、新しい接続はプリンシパル サーバーとなったミラー データベースに透過的にリダイレクトされます。クライアントが接続文字列またはデータ ソース オブジェクトを変更する必要はありません。

接続が最初に確立されると、プリンシパル サーバーはフェールオーバー パートナーの ID を、フェールオーバー発生時に使用されるクライアントに送信します。アプリケーションが障害の発生したプリンシパル サーバーと最初の接続を確立しようとするとき、フェールオーバー パートナーの ID はクライアントに通知されていません。クライアントがこのシナリオに対処できるように、failoverPartner 接続文字列プロパティ、およびオプションで setFailoverPartner データ ソース メソッドを使用することで、クライアントはフェールオーバー パートナーの ID を独自に指定できます。クライアント プロパティはこのシナリオでのみ使用されます。プリンシパル サーバーが利用可能な場合は使用されません。

注メモ :

接続文字列またはデータ ソース オブジェクトで failoverPartner が指定されている場合は、databaseName プロパティも設定する必要があります。これが設定されていないと、例外がスローされます。failoverPartner および databaseName が明示的に指定されていないと、プリンシパル データベース サーバーに障害が発生した場合に、アプリケーションがフェールオーバーを実行しません。つまり、透過的なリダイレクトは、failoverPartner および databaseName が明示的に指定された接続に対してのみ機能します。failoverPartner およびその他の接続文字列プロパティの詳細については、「接続プロパティの設定」を参照してください。

クライアントで指定されたフェールオーバー パートナー サーバーが、指定されたデータベースのフェールオーバー パートナーの役割を担っているサーバーを指していない場合、接続はサーバーによって拒否されます。SQLServerDataSource クラスは getFailoverPartner メソッドを提供しますが、このメソッドは接続文字列または setFailoverPartner メソッドで指定されたフェールオーバー パートナーの名前のみを返します。現在使用されている実際のフェールオーバー パートナーの名前を取得するには、次の Transact-SQL ステートメントを使用します。

SELECT m.mirroring_role_DESC, m.mirroring_state_DESC,
m.mirroring_partner_instance FROM sys.databases as db,
sys.database_mirroring AS m WHERE db.name = 'MirroringDBName'
AND db.database_id = m.database_id
注メモ :

ミラーリング データベースの名前を使用するには、このステートメントを変更する必要があります。

接続の最初の試行が失敗した場合に備えて、接続文字列を更新するか、または再試行の戦略を立てるために、パートナー情報をキャッシュすることを検討してください。

次の例では、最初にプリンシパル サーバーへの接続が試行されます。接続に失敗して例外がスローされた場合、ミラー サーバーへの接続が試行されます。ミラー サーバーは新しいプリンシパル サーバーに昇格している可能性があります。接続文字列での failoverPartner プロパティの使用に注意してください。

import java.sql.*;

public class clientFailover {

   public static void main(String[] args) {

      // Create a variable for the connection string.
      String connectionUrl = "jdbc:sqlserver://serverA:1433;" +
         "databaseName=AdventureWorks;integratedSecurity=true;" +
         "failoverPartner=serverB";

      // Declare the JDBC objects.
      Connection con = null;
      Statement stmt = null;

      try {
         // Establish the connection to the principal server.
         Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
         con = DriverManager.getConnection(connectionUrl);
         System.out.println("Connected to the principal server.");

         // Note that if a failover of serverA occurs here, then an
         // exception will be thrown and the failover partner will
         // be used in the first catch block below.

         // Create and execute an SQL statement that inserts some data.
         stmt = con.createStatement();

         // Note that the following statement assumes that the 
         // TestTable table has been created in the AdventureWorks
         // sample database.
         stmt.executeUpdate("INSERT INTO TestTable (Col2, Col3) VALUES ('a', 10)");
      }

      // Handle any errors that may have occurred.
      catch (SQLException se) {
         try {
            // The connection to the principal server failed,
            // try the mirror server which may now be the new
            // principal server.
            System.out.println("Connection to principal server failed, " +
            "trying the mirror server.");
            con = DriverManager.getConnection(connectionUrl);
            System.out.println("Connected to the new principal server.");
            stmt = con.createStatement();
            stmt.executeUpdate("INSERT INTO TestTable (Col2, Col3) VALUES ('a', 10)");
         }
         catch (Exception e) {
            e.printStackTrace();
         }
      }
      catch (Exception e) {
         e.printStackTrace();
      }
      // Close the JDBC objects.
      finally {
         if (stmt != null) try { stmt.close(); } catch(Exception e) {}
         if (con != null) try { con.close(); } catch(Exception e) {}
      }
   }
}

参照

その他の技術情報

JDBC ドライバによる SQL Server への接続