SQL Serverの回復保留中または疑わしい状態のAlways On可用性データベースのトラブルシューティング
この記事では、または 状態にある Microsoft SQL Serverの可用性データベースのエラーと制限事項、および可用性グループのRecovery Pending
Suspect
完全な機能にデータベースを復元する方法について説明します。
元の製品バージョン: 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
実行して、障害が発生した可用性データベースをホストしているレプリカを削除します。 それには、以下の手順を実行します。
次の手順では、プライマリ レプリカが最初に破損したデータベースをホストすることを前提としています。 そのため、破損したデータベースをホストしているレプリカをセカンダリ ロールに移行するには、まずフェールオーバーが発生する必要があります。
SQL Serverを実行しており、セカンダリ レプリカをホストしているサーバーに接続します。
次の SQL スクリプトを実行します。
ALTER AVAILABILITY GROUP <AvailabilityGroupName> FAILOVER
次の SQL スクリプトを実行して、破損したデータベースをホストしているレプリカを可用性グループから削除します。
ALTER AVAILABILITY GROUP <AvailabilityGroupName> REMOVE REPLICA ON '<SQLServerNodeName>'
SQL Serverを実行しており、データベースの障害に影響する可能性があるサーバー上の問題を解決します。
可用性グループにレプリカを再度追加します。
プライマリ レプリカが可用性グループ内の唯一のレプリカである場合の解決
プライマリ レプリカが破損したデータベースをホストし、可用性グループ内の唯一の動作レプリカである場合は、可用性グループを削除する必要があります。 可用性グループが削除された後、データベースをバックアップから復旧することも、データベースを復元したり、運用を再開したりするために、その他の緊急復旧作業を適用することもできます。
可用性グループを削除するには、次の SQL スクリプトを使用します。
DROP AVAILABILITY GROUP <AvailabilityGroupName>
この時点で、問題のあるデータベースの復旧を試みることができます。 または、最後に既知の正常なバックアップ コピーからデータベースを復元することもできます。
可用性グループを削除するときの解決策
可用性グループを削除すると、リスナー リソースも削除され、可用性データベースへのアプリケーション接続が中断されます。
アプリケーションのダウンタイムを最小限に抑えるには、次のいずれかの方法を使用して、リスナーを介したアプリケーション接続を維持し、可用性グループを削除します。
方法 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 )
フェールオーバー クラスター マネージャーを起動し、左側のウィンドウで [ロール ] を選択します。 ロールの一覧が表示されたウィンドウで、元の可用性グループを選択します。
下部中央のウィンドウの [ リソース ] タブで、可用性グループ リソースを右クリックし、[プロパティ] を選択 します。 [ 依存関係 ] タブを選択し、リスナーへの依存関係を削除し、[ OK] を選択します。
リソースの下でリスナーを右クリックし、[ その他のアクション] を選択し、[ 別のロールに割り当てる] を選択します。
[ ロールへのソースの割り当て ] ダイアログ ボックスで、新しい可用性グループを選択し、[ OK] を選択します。
[ ロール ] ウィンドウで、新しい可用性グループを選択します。 下部中央のウィンドウの [ リソース ] タブに、新しい可用性グループとリスナー リソースが表示されます。 新しい可用性グループ リソースを右クリックし、[プロパティ] を選択 します。
[ 依存関係 ] タブをクリックし、ドロップダウン ボックスからリスナー リソースを選択し、[OK] を選択します。
SQL Server Management Studioで、オブジェクト エクスプローラーを使用して、新しい可用性グループのプライマリ レプリカをホストするSQL Serverのインスタンスに接続します。 [高可用性Always On選択し、新しい可用性グループをクリックし、[可用性グループ リスナー] を選択します。 リスナーが見つかるはずです。
リスナーを右クリックし、[ プロパティ] を選択し、リスナーに適切なポート番号を入力して、[ OK] を選択します。
これにより、リスナーを使用するアプリケーションは、中断することなく、運用環境のデータベースをホストしているSQL Serverのインスタンスに接続するために引き続き使用できます。 元の可用性グループを完全に削除して再作成できるようになりました。 または、データベースとレプリカを新しい可用性グループに追加することもできます。
元の可用性グループを再作成する場合は、リスナーを可用性グループ ロールに再割り当てし、新しい可用性グループ リソースとリスナーの間の依存関係を設定してから、リスナーにポートを再割り当てする必要があります。 これを行うには、次の手順を実行します。
- フェールオーバー クラスター マネージャーを起動し、左側のウィンドウで [ロール ] を選択します。 ロールの一覧が表示されたウィンドウで、リスナーをホストする新しい可用性グループをクリックします。
- 下部中央のウィンドウの [ リソース ] タブで、リスナーを右クリックし、[ その他のアクション] を選択し、[ 別のロールに割り当てる] を選択します。 ダイアログ ボックスで、再作成された可用性グループを選択し、[ OK] を選択します。
- [ ロール ] ウィンドウで、再作成された可用性グループをクリックします。 下部中央のウィンドウの [ リソース ] タブに、再作成された可用性グループとリスナー リソースが表示されます。 再作成された可用性グループ リソースを右クリックし、[プロパティ] を選択 します。
- [ 依存関係 ] タブを選択し、ドロップダウン ボックスからリスナー リソースを選択し、[OK] を選択します。
- SQL Server Management Studioで、オブジェクト エクスプローラーを使用して、再作成された可用性グループのプライマリ レプリカをホストするSQL Serverのインスタンスに接続します。 [高可用性Always On選択し、新しい可用性グループをクリックし、[可用性グループ リスナー] を選択します。 リスナーが見つかるはずです。
- リスナーを右クリックし、[ プロパティ] を選択し、リスナーに適切なポート番号を入力して、[ OK] を選択します。
方法 2: リスナーを既存のSQL Server フェールオーバー クラスター化インスタンス (SQLFCI) に関連付ける
SQL Server フェールオーバー クラスター化インスタンス (SQLFCI) で可用性グループをホストしている場合は、リスナークラスター化リソースを SQLFCI クラスター化リソース グループに関連付けてから、可用性グループを削除してから再作成できます。
フェールオーバー クラスター マネージャーを起動し、左側のウィンドウで [ロール ] を選択します。
ロールの一覧が表示されたウィンドウで、元の可用性グループを選択します。
下部中央のウィンドウの [ リソース ] タブで、可用性グループ リソースを右クリックし、[プロパティ] を選択 します。
[ 依存関係 ] タブを選択し、リスナーへの依存関係を削除し、[ OK] を選択します。
下部中央のウィンドウの [ リソース ] タブで、リスナーを右クリックし、[ その他のアクション] を選択し、[ 別のロールに割り当てる] を選択します。
[ロールへのリソースの割り当て] ダイアログ ボックスで、SQL SERVER FCI インスタンスをクリックし、[OK] を選択します。
[ ロール ] ウィンドウで、SQLFCI グループを選択します。 下部中央のウィンドウの [ リソース ] タブに、新しいリスナー リソースが表示されます。
これにより、リスナーを使用するアプリケーションでも、中断することなく運用データベースをホストするSQL Serverのインスタンスに接続できます。 元の可用性グループを削除して再作成できるようになりました。 または、データベースとレプリカを新しい可用性グループに追加することもできます。
可用性グループが再作成されたら、リスナーを可用性グループ ロールに再割り当てします。 次に、新しい可用性グループ リソースとリスナーの間の依存関係を設定し、リスナーにポートを再割り当てします。
- フェールオーバー クラスター マネージャーを起動し、左側のウィンドウで [ロール ] を選択します。
- ロールの一覧が表示されたウィンドウで、元の SQLFCI ロールをクリックします。
- 下部中央のウィンドウの [ リソース ] タブで、リスナーを右クリックし、[ その他のアクション] を選択し、[ 別のロールに割り当てる] を選択します。
- ダイアログ ボックスで、再作成された可用性グループをクリックし、[OK] を選択 します。
- [ ロール ] ウィンドウで、新しい可用性グループを選択します。
- [ リソース ] タブに、新しい可用性グループとリスナー リソースが表示されます。 新しい可用性グループ リソースを右クリックし、[プロパティ] を選択 します。
- [ 依存関係 ] タブを選択し、ドロップダウン ボックスからリスナー リソースを選択し、[OK] を選択します。
- SQL Server Management Studioで、オブジェクト エクスプローラーを使用して、新しい可用性グループのプライマリ レプリカをホストするSQL Serverのインスタンスに接続します。
- [高可用性Always On選択し、新しい可用性グループをクリックし、[可用性グループ リスナー] を選択します。 リスナーが見つかるはずです。
- リスナーを右クリックし、[ プロパティ] を選択し、リスナーに適切なポート番号を入力して、[ OK] を選択します。
方法 3: 可用性グループを削除し、同じリスナー名で可用性グループとリスナーを再作成する
この方法では、可用性グループとリスナーが削除されてから再作成されるため、現在接続されているアプリケーションの停止が少なくなります。
可用性グループを削除します。
注:
これにより、リスナーも削除されます。
実稼働データベースをホストするのと同じサーバー上に、リスナー定義を含む新しい空の可用性グループをすぐに作成します。
たとえば、可用性グループ リスナーが 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
破損したデータベースを復旧します。 次に、それを追加し、セカンダリ レプリカを可用性グループに戻します。