SQL Server の回復保留中または未確認状態の Always On 可用性データベースをトラブルシューティングする
この記事では、 Recovery Pending
または Suspect
状態にある Microsoft SQL Server の可用性データベースのエラーと制限事項、および可用性グループの完全な機能にデータベースを復元する方法について説明します。
元の製品バージョン: SQL Server 2012
元の KB 番号: 2857849
まとめ
Always On 可用性グループで定義されている可用性データベースが、SQL Server の Recovery Pending
または Suspect
状態に移行するとします。 可用性グループのプライマリ レプリカでこれが発生した場合、データベースの可用性が影響を受ける。 この状況では、クライアント アプリケーションを介してデータベースにアクセスすることはできません。 さらに、可用性グループからデータベースを削除したり削除したりすることはできません。
たとえば、SQL Server が実行されていて、可用性データベースが Recovery Pending
または Suspect
状態に設定されているとします。 次の SQL スクリプトを使用してプライマリ レプリカの動的管理ビュー (DMV) に対してクエリを実行すると、次のようにデータベースが NOT_HEALTHY
および RECOVERY_PENDING
状態または SUSPECT
状態で報告されることがあります。
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 の Not Synchronizing /Recovery Pending または Suspect 状態であると報告される場合があります。
データベースが可用性グループで定義されている場合、データベースを削除または復元することはできません。 そのため、データベースを復旧して運用環境での使用に戻すには、特定の手順を実行する必要があります。
詳細
次の内容では、さまざまな状況で復旧保留中状態にある可用性データベースのエラーと制限事項について説明します。
データベースの状態がデータベースの復元を妨げる
次の SQL スクリプトを実行して、
RECOVERY
パラメーターを持つデータベースを復元しようとするとします。RESTORE DATABASE <DatabaseName> WITH RECOVERY
このスクリプトを実行すると、データベースが可用性グループで定義されているため、次のエラー メッセージが表示されます。
メッセージ 3104、レベル 16、状態 1、行 1
RESTORE はデータベース ミラーリング用に構成されているか>可用性グループに参加しているため、データベース <DatabaseName では動作できません。 データベースを復元する場合は、ALTER DATABASE を使用してミラーリングを削除するか、可用性グループからデータベースを削除します。メッセージ 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> はまだ復旧されていません。 しばらく待ってから再試行してください。
データベースがセカンダリ ロールにある場合の解決方法
この問題を解決するには、次の一般的なアクションを実行します。
- データベースがセカンダリ ロールにあるときに、破損したデータベースをホストしているレプリカを可用性グループから削除します。
- システムに影響を与え、データベース障害の原因になった可能性のある問題を解決します。
- 可用性グループにレプリカを復元します。
これらのアクションを実行するには、新しいプライマリ レプリカに接続し、 ALTER AVAILABILITY GROUP
SQL スクリプトを実行して、障害が発生した可用性データベースをホストしているレプリカを削除します。 これを行うには、以下の手順を実行します。
これらの手順では、プライマリ レプリカが最初に破損したデータベースをホストしていることを前提としています。 そのため、破損したデータベースをホストしているレプリカをセカンダリ ロールに移行するには、最初にフェールオーバーが発生する必要があります。
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 )
フェールオーバー クラスター マネージャーを起動し、左側のウィンドウで Roles を選択します。 ロールの一覧が表示されたウィンドウで、元の可用性グループを選択します。
Resources タブの下の中央のウィンドウで、可用性グループ リソースを右クリックし、Properties を選択します。 Dependencies タブを選択し、リスナーへの依存関係を削除してから、OKを選択します。
リソースの下でリスナーを右クリックし、[ その他のアクション] を選択し、[ 別のロールに割り当てを選択します。
[ソースからロールへの割り当て] ダイアログ ボックスで、新しい可用性グループを選択し、[OKを選択します。
Roles ペインで、新しい可用性グループを選択します。 中央下部のウィンドウの Resources タブに、新しい可用性グループとリスナー リソースが表示されます。 新しい可用性グループ リソースを右クリックし、 Properties を選択します。
[ Dependencies タブをクリックし、ドロップダウン ボックスからリスナー リソースを選択し、 OK を選択します。
SQL Server Management Studio で、オブジェクト エクスプローラーを使用して、新しい可用性グループのプライマリ レプリカをホストする SQL Server のインスタンスに接続します。 Always On High Availabilityを選択し、新しい可用性グループをクリックして、Availability グループ リスナーを選択します。 リスナーが見つかります。
リスナーを右クリックし、 Properties を選択し、リスナーの適切なポート番号を入力して、 OKを選択します。
これにより、リスナーを使用するアプリケーションでも、それを使用して、運用データベースをホストしている SQL Server のインスタンスに中断なく接続できるようになります。 元の可用性グループを完全に削除して再作成できるようになりました。 または、データベースとレプリカを新しい可用性グループに追加できます。
元の可用性グループを再作成する場合は、リスナーを可用性グループ ロールに再割り当てし、新しい可用性グループ リソースとリスナーの間の依存関係を設定してから、リスナーにポートを再割り当てする必要があります。 これを行うには、次の手順を実行します。
- フェールオーバー クラスター マネージャーを起動し、左側のウィンドウで Roles を選択します。 ロールの一覧が表示されたウィンドウで、リスナーをホストする新しい可用性グループをクリックします。
- Resources タブの下の中央のウィンドウで、リスナーを右クリックし、[その他のアクション]を選択し、[別のロールに割り当て] を選択します。 ダイアログ ボックスで、再作成された可用性グループを選択し、 OKを選択します。
- Roles ペインで、再作成された可用性グループをクリックします。 中央下部のウィンドウの Resources タブに、再作成された可用性グループとリスナー リソースが表示されます。 再作成された可用性グループ リソースを右クリックし、 Properties を選択します。
- [ Dependencies タブを選択し、ドロップダウン ボックスからリスナー リソースを選択し、 OK を選択します。
- SQL Server Management Studio で、オブジェクト エクスプローラーを使用して、再作成された可用性グループのプライマリ レプリカをホストする SQL Server のインスタンスに接続します。 Always On High Availabilityを選択し、新しい可用性グループをクリックして、Availability グループ リスナーを選択します。 リスナーが見つかります。
- リスナーを右クリックし、 Properties を選択し、リスナーの適切なポート番号を入力して、 OKを選択します。
方法 2: リスナーを既存の SQL Server フェールオーバー クラスター インスタンス (SQLFCI) に関連付ける
SQL Server フェールオーバー クラスター化インスタンス (SQLFCI) で可用性グループをホストしている場合は、リスナーのクラスター化されたリソースを SQLFCI クラスター化リソース グループに関連付け、削除してから可用性グループを再作成できます。
フェールオーバー クラスター マネージャーを起動し、左側のウィンドウで Roles を選択します。
ロールの一覧が表示されたウィンドウで、元の可用性グループを選択します。
下部中央のウィンドウの Resources タブで、可用性グループ リソースを右クリックし、 Properties を選択します。
Dependencies タブを選択し、リスナーへの依存関係を削除してから、OKを選択します。
Resources タブの下の中央のウィンドウで、リスナーを右クリックし、[その他のアクション]を選択し、[別のロールに割り当て] を選択します。
リソースのロールへの割り当て ダイアログ ボックスで、SQL Server FCI インスタンスをクリックし、OKを選択します。
Roles ペインで、SQLFCI グループを選択します。 中央下部のウィンドウの Resources タブに、新しいリスナー リソースが表示されます。
これにより、リスナーを使用するアプリケーションでは、中断なしに運用データベースをホストする SQL Server のインスタンスに接続するためにリスナーを引き続き使用できます。 元の可用性グループを削除して再作成できるようになりました。 または、データベースとレプリカを新しい可用性グループに追加できます。
可用性グループが再作成されたら、リスナーを可用性グループ ロールに再割り当てします。 次に、新しい可用性グループ リソースとリスナーの間の依存関係を設定し、リスナーにポートを再割り当てします。
- フェールオーバー クラスター マネージャーを起動し、左側のウィンドウで Roles を選択します。
- ロールの一覧が表示されたウィンドウで、元の SQLFCI ロールをクリックします。
- 中央下部のウィンドウの Resources タブで、リスナーを右クリックし、[ その他のアクション] を選択し、[ 別のロールに割り当てを選択します。
- ダイアログ ボックスで、再作成された可用性グループをクリックし、 OK を選択します。
- Roles ペインで、新しい可用性グループを選択します。
- Resources タブに、新しい可用性グループとリスナー リソースが表示されます。 新しい可用性グループ リソースを右クリックし、 Properties を選択します。
- [ Dependencies タブを選択し、ドロップダウン ボックスからリスナー リソースを選択し、 OK を選択します。
- SQL Server Management Studio で、オブジェクト エクスプローラーを使用して、新しい可用性グループのプライマリ レプリカをホストする SQL Server のインスタンスに接続します。
- Always On High Availabilityを選択し、新しい可用性グループをクリックして、Availability グループ リスナーを選択します。 リスナーが見つかります。
- リスナーを右クリックし、 Properties を選択し、リスナーの適切なポート番号を入力して、 OKを選択します。
方法 3: 可用性グループを削除し、同じリスナー名で可用性グループとリスナーを再作成する
この方法では、可用性グループとリスナーが削除されて再作成されるため、現在接続されているアプリケーションに対して小規模な停止が発生します。
可用性グループを削除します。
Note
これにより、リスナーも削除されます。
実稼働データベースをホストするのと同じサーバー上に、リスナー定義を含む新しい空の可用性グループをすぐに作成します。
たとえば、可用性グループ リスナーが 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
破損したデータベースを復旧します。 次に、それを追加し、セカンダリ レプリカを可用性グループに戻します。