SQL Serverの回復保留中または疑わしい状態のAlways On可用性データベースのトラブルシューティング

この記事では、または 状態にある Microsoft SQL Serverの可用性データベースのエラーと制限事項、および可用性グループのRecovery PendingSuspect完全な機能にデータベースを復元する方法について説明します。

元の製品バージョン: SQL Server 2012
元の KB 番号: 2857849

概要

Always On可用性グループで定義されている可用性データベースが、SQL Server の または Suspect 状態にRecovery Pending移行すると想定します。 可用性グループのプライマリ レプリカでこれが発生した場合、データベースの可用性が影響を受ける。 この状況では、クライアント アプリケーションを介してデータベースにアクセスすることはできません。 また、可用性グループからデータベースを削除したり削除したりすることはできません。

たとえば、SQL Serverが実行されていて、可用性データベースが または Suspect 状態にRecovery Pending設定されているとします。 次の SQL スクリプトを使用してプライマリ レプリカの動的管理ビュー (DMV) に対してクエリを実行すると、データベースが次のように and RECOVERY_PENDING 状態または状態でSUSPECT報告NOT_HEALTHYされる場合があります。

SELECT
    dc.database_name,
    d.synchronization_health_desc,
    d.synchronization_state_desc,
    d.database_state_desc
FROM
    sys.dm_hadr_database_replica_states d
    JOIN sys.availability_databases_cluster dc ON d.group_database_id = dc.group_database_id
    AND d.is_local = 1
database_name          synchronization_health_desc     synchronization_state_desc   database_state_desc
-------------------- ------------------------------ ------------------------------ ---------------------
<DatabaseName>                         NOT_HEALTHY              NOT SYNCHRONIZING      RECOVERY_PENDING
(1 row(s) affected)

データベースの正常性と同期の状態をチェックするスクリプトの実行結果のスクリーンショット。

さらに、このデータベースは、SQL Server Management Studioの [同期中/回復が保留中でない] または [疑わしい] 状態にあると報告される場合があります。

同期されていない/回復保留中の状態にあるデータベースのスクリーンショット。

データベースが可用性グループで定義されている場合、データベースを削除または復元することはできません。 そのため、データベースを復旧し、運用環境で使用するために特定の手順を実行する必要があります。

詳細

次の内容では、さまざまな状況で回復保留中状態にある可用性データベースのエラーと制限事項について説明します。

  • データベースの状態がデータベースの復元を妨げる

    次の SQL スクリプトを実行して、 パラメーターを持つデータベースを RECOVERY 復元しようとするとします。

    RESTORE DATABASE <DatabaseName> WITH RECOVERY
    

    このスクリプトを実行すると、データベースが可用性グループで定義されているため、次のエラー メッセージが表示されます。

    メッセージ 3104、レベル 16、状態 1、行 1
    DATABASE DatabaseName> はデータベース <ミラーリング用に構成されているか、可用性グループに参加しているため、RESTORE を操作できません。 データベースを復元する場合は、ALTER DATABASE を使用してミラーリングを削除するか、可用性グループからデータベースを削除します。

    Msg 3013、レベル 16、状態 1、行 1
    RESTORE DATABASE が異常終了しています。

  • データベースの状態によってデータベースが削除されないようにする

    次の SQL スクリプトを実行してデータベースを削除しようとするとします。

    DROP DATABASE <DatabaseName>
    

    このスクリプトを実行すると、データベースが可用性グループで定義されているため、次のエラー メッセージが表示されます。

    メッセージ 3752、レベル 16、状態 1、行 1
    データベース <DatabaseName> は現在、可用性グループに参加しています。 データベースを削除する前に、可用性グループからデータベースを削除する必要があります。

  • データベースの状態により、可用性グループからデータベースが削除されないようにする

    次の SQL スクリプトを実行して、可用性グループからデータベースを削除しようとするとします。

    ALTER DATABASE <DatabaseName> SET hadr OFF
    

    このスクリプトを実行しようとすると、可用性データベースがプライマリ レプリカに属しているため、次のエラー メッセージが表示されます。

    メッセージ 35240、レベル 16、状態 14、行 1
    Database <DatabaseName> は、可用性グループ AvailabilityGroupName> に参加することも、可用性グループ<から参加解除することもできません。 この操作は、可用性グループのプライマリ レプリカではサポートされていません。

    このエラー メッセージが原因で、データベースのフェールオーバーを強制される場合があります。 データベースがフェールオーバーされると、復旧保留中のデータベースを所有するレプリカがセカンダリ ロールになります。 このような場合は、次の SQL スクリプトをもう一度実行して、セカンダリ レプリカの可用性グループからデータベースを削除します。

    ALTER DATABASE <DatabaseName> SET hadr OFF
    

    ただし、引き続き可用性グループからデータベースを削除することはできません。データベースがまだ回復保留中状態であるため、次のエラー メッセージが表示されます。

    メッセージ 921、レベル 16、状態 112、行 1
    Database <DatabaseName> はまだ復旧されていません。 待ってからやり直してください。

データベースがセカンダリ ロールにある場合の解決

この問題を解決するには、次の一般的なアクションを実行します。

  • データベースがセカンダリ ロールにあるときに、破損したデータベースをホストしているレプリカを可用性グループから削除します。
  • システムに影響を与え、データベース障害の原因になっている可能性がある問題を解決します。
  • レプリカを可用性グループに復元します。

これらのアクションを実行するには、新しいプライマリ レプリカに接続し、SQL スクリプトを ALTER AVAILABILITY GROUP 実行して、障害が発生した可用性データベースをホストしているレプリカを削除します。 それには、以下の手順を実行します。

次の手順では、プライマリ レプリカが最初に破損したデータベースをホストすることを前提としています。 そのため、破損したデータベースをホストしているレプリカをセカンダリ ロールに移行するには、まずフェールオーバーが発生する必要があります。

  1. SQL Serverを実行しており、セカンダリ レプリカをホストしているサーバーに接続します。

  2. 次の SQL スクリプトを実行します。

    ALTER AVAILABILITY GROUP <AvailabilityGroupName> FAILOVER
    
  3. 次の SQL スクリプトを実行して、破損したデータベースをホストしているレプリカを可用性グループから削除します。

    ALTER AVAILABILITY GROUP <AvailabilityGroupName> REMOVE REPLICA ON '<SQLServerNodeName>'
    
  4. SQL Serverを実行しており、データベースの障害に影響する可能性があるサーバー上の問題を解決します。

  5. 可用性グループにレプリカを再度追加します。

プライマリ レプリカが可用性グループ内の唯一のレプリカである場合の解決

プライマリ レプリカが破損したデータベースをホストし、可用性グループ内の唯一の動作レプリカである場合は、可用性グループを削除する必要があります。 可用性グループが削除された後、データベースをバックアップから復旧することも、データベースを復元したり、運用を再開したりするために、その他の緊急復旧作業を適用することもできます。

可用性グループを削除するには、次の SQL スクリプトを使用します。

DROP AVAILABILITY GROUP <AvailabilityGroupName>

この時点で、問題のあるデータベースの復旧を試みることができます。 または、最後に既知の正常なバックアップ コピーからデータベースを復元することもできます。

可用性グループを削除するときの解決策

可用性グループを削除すると、リスナー リソースも削除され、可用性データベースへのアプリケーション接続が中断されます。

アプリケーションのダウンタイムを最小限に抑えるには、次のいずれかの方法を使用して、リスナーを介したアプリケーション接続を維持し、可用性グループを削除します。

方法 1: フェールオーバー クラスター マネージャーでリスナーを新しい可用性グループ (ロール) に関連付ける

このメソッドを使用すると、可用性グループの削除と再作成中にリスナーを維持できます。

  1. 既存の可用性グループ リスナーが接続を指示しているSQL Serverのインスタンスで、新しい空の可用性グループを作成します。 このプロセスを簡略化するには、Transact-SQL コマンドを使用して、セカンダリ レプリカまたはデータベースを持たない可用性グループを作成します。

    USE master
    GO
    CREATE AVAILABILITY GROUP ag FOR REPLICA ON 'sqlnode1' WITH (
        ENDPOINT_URL = 'tcp://sqlnode1:5022',
        AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
        FAILOVER_MODE = MANUAL
    )
    
  2. フェールオーバー クラスター マネージャーを起動し、左側のウィンドウで [ロール ] を選択します。 ロールの一覧が表示されたウィンドウで、元の可用性グループを選択します。

  3. 下部中央のウィンドウの [ リソース ] タブで、可用性グループ リソースを右クリックし、[プロパティ] を選択 します。 [ 依存関係 ] タブを選択し、リスナーへの依存関係を削除し、[ OK] を選択します

    可用性グループのプロパティの [依存関係] タブのスクリーンショット。

  4. リソースの下でリスナーを右クリックし、[ その他のアクション] を選択し、[ 別のロールに割り当てる] を選択します。

  5. [ ロールへのソースの割り当て ] ダイアログ ボックスで、新しい可用性グループを選択し、[ OK] を選択します

    [ロールへのソースの割り当て] ダイアログ ボックスのスクリーンショット。追加された新しい可用性グループが表示されています。

  6. [ ロール ] ウィンドウで、新しい可用性グループを選択します。 下部中央のウィンドウの [ リソース ] タブに、新しい可用性グループとリスナー リソースが表示されます。 新しい可用性グループ リソースを右クリックし、[プロパティ] を選択 します

  7. [ 依存関係 ] タブをクリックし、ドロップダウン ボックスからリスナー リソースを選択し、[OK] を選択します

    新しい可用性グループのプロパティの [依存関係] タブのスクリーンショット。

  8. SQL Server Management Studioで、オブジェクト エクスプローラーを使用して、新しい可用性グループのプライマリ レプリカをホストするSQL Serverのインスタンスに接続します。 [高可用性Always On選択し、新しい可用性グループをクリックし、[可用性グループ リスナー] を選択します。 リスナーが見つかるはずです。

  9. リスナーを右クリックし、[ プロパティ] を選択し、リスナーに適切なポート番号を入力して、[ OK] を選択します

    リスナーの構成を示す可用性グループ リスナープロパティのスクリーンショット。

これにより、リスナーを使用するアプリケーションは、中断することなく、運用環境のデータベースをホストしているSQL Serverのインスタンスに接続するために引き続き使用できます。 元の可用性グループを完全に削除して再作成できるようになりました。 または、データベースとレプリカを新しい可用性グループに追加することもできます。

元の可用性グループを再作成する場合は、リスナーを可用性グループ ロールに再割り当てし、新しい可用性グループ リソースとリスナーの間の依存関係を設定してから、リスナーにポートを再割り当てする必要があります。 これを行うには、次の手順を実行します。

  1. フェールオーバー クラスター マネージャーを起動し、左側のウィンドウで [ロール ] を選択します。 ロールの一覧が表示されたウィンドウで、リスナーをホストする新しい可用性グループをクリックします。
  2. 下部中央のウィンドウの [ リソース ] タブで、リスナーを右クリックし、[ その他のアクション] を選択し、[ 別のロールに割り当てる] を選択します。 ダイアログ ボックスで、再作成された可用性グループを選択し、[ OK] を選択します
  3. [ ロール ] ウィンドウで、再作成された可用性グループをクリックします。 下部中央のウィンドウの [ リソース ] タブに、再作成された可用性グループとリスナー リソースが表示されます。 再作成された可用性グループ リソースを右クリックし、[プロパティ] を選択 します
  4. [ 依存関係 ] タブを選択し、ドロップダウン ボックスからリスナー リソースを選択し、[OK] を選択します
  5. SQL Server Management Studioで、オブジェクト エクスプローラーを使用して、再作成された可用性グループのプライマリ レプリカをホストするSQL Serverのインスタンスに接続します。 [高可用性Always On選択し、新しい可用性グループをクリックし、[可用性グループ リスナー] を選択します。 リスナーが見つかるはずです。
  6. リスナーを右クリックし、[ プロパティ] を選択し、リスナーに適切なポート番号を入力して、[ OK] を選択します

方法 2: リスナーを既存のSQL Server フェールオーバー クラスター化インスタンス (SQLFCI) に関連付ける

SQL Server フェールオーバー クラスター化インスタンス (SQLFCI) で可用性グループをホストしている場合は、リスナークラスター化リソースを SQLFCI クラスター化リソース グループに関連付けてから、可用性グループを削除してから再作成できます。

  1. フェールオーバー クラスター マネージャーを起動し、左側のウィンドウで [ロール ] を選択します。

  2. ロールの一覧が表示されたウィンドウで、元の可用性グループを選択します。

  3. 下部中央のウィンドウの [ リソース ] タブで、可用性グループ リソースを右クリックし、[プロパティ] を選択 します

  4. [ 依存関係 ] タブを選択し、リスナーへの依存関係を削除し、[ OK] を選択します

  5. 下部中央のウィンドウの [ リソース ] タブで、リスナーを右クリックし、[ その他のアクション] を選択し、[ 別のロールに割り当てる] を選択します。

  6. [ロールへのリソースの割り当て] ダイアログ ボックスで、SQL SERVER FCI インスタンスをクリックし、[OK] を選択します

    [リソースをロールに割り当てる] ダイアログ ボックスのスクリーンショット。

  7. [ ロール ] ウィンドウで、SQLFCI グループを選択します。 下部中央のウィンドウの [ リソース ] タブに、新しいリスナー リソースが表示されます。

これにより、リスナーを使用するアプリケーションでも、中断することなく運用データベースをホストするSQL Serverのインスタンスに接続できます。 元の可用性グループを削除して再作成できるようになりました。 または、データベースとレプリカを新しい可用性グループに追加することもできます。

可用性グループが再作成されたら、リスナーを可用性グループ ロールに再割り当てします。 次に、新しい可用性グループ リソースとリスナーの間の依存関係を設定し、リスナーにポートを再割り当てします。

  1. フェールオーバー クラスター マネージャーを起動し、左側のウィンドウで [ロール ] を選択します。
  2. ロールの一覧が表示されたウィンドウで、元の SQLFCI ロールをクリックします。
  3. 下部中央のウィンドウの [ リソース ] タブで、リスナーを右クリックし、[ その他のアクション] を選択し、[ 別のロールに割り当てる] を選択します。
  4. ダイアログ ボックスで、再作成された可用性グループをクリックし、[OK] を選択 します
  5. [ ロール ] ウィンドウで、新しい可用性グループを選択します。
  6. [ リソース ] タブに、新しい可用性グループとリスナー リソースが表示されます。 新しい可用性グループ リソースを右クリックし、[プロパティ] を選択 します
  7. [ 依存関係 ] タブを選択し、ドロップダウン ボックスからリスナー リソースを選択し、[OK] を選択します
  8. SQL Server Management Studioで、オブジェクト エクスプローラーを使用して、新しい可用性グループのプライマリ レプリカをホストするSQL Serverのインスタンスに接続します。
  9. [高可用性Always On選択し、新しい可用性グループをクリックし、[可用性グループ リスナー] を選択します。 リスナーが見つかるはずです。
  10. リスナーを右クリックし、[ プロパティ] を選択し、リスナーに適切なポート番号を入力して、[ OK] を選択します

方法 3: 可用性グループを削除し、同じリスナー名で可用性グループとリスナーを再作成する

この方法では、可用性グループとリスナーが削除されてから再作成されるため、現在接続されているアプリケーションの停止が少なくなります。

  1. 可用性グループを削除します。

    注:

    これにより、リスナーも削除されます。

  2. 実稼働データベースをホストするのと同じサーバー上に、リスナー定義を含む新しい空の可用性グループをすぐに作成します。

    たとえば、可用性グループ リスナーが aglisten であるとします。 次の Transact-SQL ステートメントは、プライマリ データベースまたはセカンダリ データベースを持たない可用性グループを作成しますが、 aglisten という名前のリスナーも作成します。 アプリケーションでは、このリスナーを使用して接続できます。

    USE master
    GO
        CREATE AVAILABILITY GROUP ag FOR REPLICA ON 'sqlnode1' WITH (
            ENDPOINT_URL = 'tcp://sqlnode1:5022',
            AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
            FAILOVER_MODE = MANUAL
        ) LISTENER 'aglisten' (
            WITH IP ((N'11.0.0.25', N'255.0.0.0')),
            PORT = 1433
        )
    GO
    
  3. 破損したデータベースを復旧します。 次に、それを追加し、セカンダリ レプリカを可用性グループに戻します。