Always On可用性グループでの復旧キューのトラブルシューティング

この記事では、復旧キューに関連する問題の解決策について説明します。

復旧キューとは

可用性グループ データベースのプライマリ レプリカに加えられた変更は、同じ可用性グループで定義されているすべてのセカンダリ レプリカに送信されます。 これらの変更がセカンダリ レプリカに到着すると、最初に可用性グループ データベースのトランザクション ログ ファイルに書き込まれます。 Microsoft SQL Serverは、復旧またはやり直し操作を使用してデータベース ファイルを更新します。

可用性グループに対する変更が、データベース トランザクション ログ ファイルに到着し、復旧できるよりも速く強化されると、 復旧キュー が形成されます。 このキューは、データベースに復旧および復元されなかった、強化されたトランザクション ログ トランザクションで構成されます。

回復 (やり直し) キューの症状と効果

プライマリ レプリカとセカンダリ レプリカに対してクエリを実行すると、さまざまな結果が返されます

セカンダリ レプリカを照会する読み取り専用ワークロードは、古いデータに対してクエリを実行する可能性があります。 復旧キューが発生した場合、同じデータを照会するときに、プライマリ レプリカ データベース上のデータに対する変更がセカンダリ データベースに反映されない可能性があります。

変更はセカンダリ データベースに到着し、データベース ログ ファイルに書き込まれますが、データベース ファイルに復旧して復元されるまで、変更は照会されません。 回復操作によって、これらの変更が読み取り可能になります。

詳細については、「Always On可用性グループの可用性モードの違い」の「セカンダリ レプリカでのデータ待機時間」セクションを参照してください。

フェールオーバー時間が長い、または RTO を超えている

目標復旧時間 (RTO) は、organizationで処理できるデータベースの最大ダウンタイムです。 RTO では、停止後にorganizationがデータベースへのアクセスを回復できる速度についても説明します。 フェールオーバーが発生したときにセカンダリ レプリカに大量の復旧キューが存在する場合、復旧に時間がかかる可能性があります。 復旧後、データベースはプライマリ ロールに移行され、フェールオーバー前に存在していたデータベースの状態を表します。 復旧時間が長いほど、フェールオーバー後の運用環境の再開速度が遅れる可能性があります。

さまざまな診断機能レポート可用性グループの回復キュー

復旧キューの場合、SQL Server Management Studio (SSMS) のAlways On ダッシュボードで異常な可用性グループが報告される場合があります。

回復 (やり直し) キューにチェックする方法

復旧キューは、プライマリ レプリカのAlways On ダッシュボードを使用するか、プライマリ レプリカまたはセカンダリ レプリカのsys.dm_hadr_database_replica_states動的管理ビュー (DMV) を使用して確認できるデータベースごとの測定値です。 パフォーマンス モニター カウンターチェック回復キューと回復率です。 これらのカウンターは、セカンダリ レプリカに対してチェックする必要があります。

次のいくつかのセクションでは、可用性グループ データベース復旧キューをアクティブに監視する方法について説明します。

クエリ sys.dm_hadr_database_replica_states

DMV は sys.dm_hadr_database_replica_states 、各可用性グループ データベースの行を報告します。 レポートの 1 つの列は です redo_queue_size。 この値は、キロバイト単位で測定された回復キュー のサイズです。 次のクエリに似たクエリを設定して、回復キュー のサイズの傾向を 30 秒ごとに監視できます。 クエリはプライマリ レプリカで実行されます。 述語を is_local=0 使用して、セカンダリ レプリカのデータを報告します。ここで redo_queue_sizeredo_rate が関連します。

WHILE 1=1
BEGIN
SELECT drcs.database_name, ars.role_desc, drs.redo_queue_size, drs.redo_rate,
ars.recovery_health_desc, ars.connected_state_desc, ars.operational_state_desc, ars.synchronization_health_desc, *
FROM sys.dm_hadr_availability_replica_states ars JOIN sys.dm_hadr_database_replica_cluster_states drcs ON ars.replica_id=drcs.replica_id
JOIN sys.dm_hadr_database_replica_states drs ON drcs.group_database_id=drs.group_database_id
WHERE ars.role_desc='SECONDARY' AND drs.is_local=0
waitfor delay '00:00:30'
END

出力の外観を次に示します。

redo_queue_sizeとredo_rateが関連するセカンダリ レプリカのデータがクエリ レポートの出力のスクリーンショット。

Always On ダッシュボードで回復キューを確認する

回復キューを確認するには、次の手順に従います。

  1. SSMS オブジェクト エクスプローラーの可用性グループを右クリックして、SSMS でAlways On ダッシュボードを開きます。

  2. [ ダッシュボードの表示] を選択します。

    可用性グループ データベースは最後に一覧表示され、データベースに関していくつかのデータが報告されます。 Redo Queue Size (KB)Redo Rate (KB/sec) は既定では表示されませんが、次の手順のスクリーンショットに示すように、このビューに追加できます。

  3. これらのカウンターを追加するには、データベース レポートの上にあるヘッダーを右クリックし、使用可能な列の一覧から選択します。

  4. Redo Queue Size (KB)Redo Rate (KB/sec) を追加するには、次のスクリーンショットで赤で強調表示されているヘッダーを右クリックします。

    カウンター Redo Queue Size (KB) と Redo Rate (KB/sec) の追加を示すスクリーンショット。

    既定では、Always On ダッシュボードでは、Redo Queue Size (KB)Redo Rate (KB/sec) が 60 秒ごとに自動更新されます。

    更新カウンターが 60 秒ごとに設定されていることを示すスクリーンショット。

パフォーマンス モニターの回復キューを確認する

回復キューのサイズは、各セカンダリ レプリカとデータベースに固有です。 したがって、可用性グループ データベースの復旧キューを確認するには、次の手順に従います。

  1. セカンダリ レプリカでパフォーマンス モニターを開きます。

  2. [ 追加 (カウンター)] ボタンを選択します。

  3. [ 使用可能なカウンター] で [ SQLServer:Database Replica] を選択し、[ 回復キュー ] と [ バイト/秒カウンターの再実行 ] を選択します。

  4. [ インスタンス ] リスト ボックスで、復旧キューを監視する可用性グループ データベースを選択します。

  5. [ OK の追加]>を選択します

    回復キューの増加は次のようになります。

    回復キューの増加を示すスクリーンショット。

リカバリー・キュー値の解釈

このセクションでは、前のセクションで決定した回復キューに関連する値を解釈する方法について説明します。

復旧キューに問題があるのはいつですか? どの程度の回復キューを許容する必要がありますか?

復旧キューが値 0 を報告している場合は、そのレポートの時点で復旧キューが発生していないと仮定する場合があります。 ただし、運用環境がビジー状態の場合は、正常な AlwaysOn 環境でも、復旧キューが 0 以外の値を頻繁に報告することを想定する必要があります。 一般的な運用環境では、この値が 0 から 0 以外の値の間で変動することを想定する必要があります。

時間の経過に伴う復旧キューの増加が観察された場合は、さらなる調査が保証されます。 この追加のアクティビティは、何かが変更されたことを示します。 回復キューの急激な増加が観察された場合、トラブルシューティングには次の測定値が役立ちます。

  • Log Redo Rate (KB/sec) (AlwaysOn ダッシュボード)
  • DMV sys.dm_hadr_database_replica_statesのRedo_rate

やり直し率のベースライン レートを取得する

正常な AlwaysOn パフォーマンス中に、ビジー状態の可用性グループ データベースの再実行率を監視します。 一般的に忙しい営業時間の間、彼らはどのように見えますか? メンテナンス期間中のこれらのレートは、大規模なトランザクション (インデックスの再構築、ETL プロセス) によってシステムのトランザクション スループットが高くなる場合に、どのようなレートになりますか? 回復キューの増加を観察するときにこれらの値を比較して、何が変更されたかを判断するのに役立ちます。 ワークロードが通常よりも大きくなる可能性があります。 やり直し率が低い場合は、理由を特定するためにさらに調査が必要になる場合があります。

ワークロード ボリュームが重要

大規模なワークロード (100 万行に対する UPDATE ステートメント、1 テラバイト テーブルでのインデックスの再構築、数百万行を挿入している ETL バッチなど) がある場合は、すぐにまたは時間の経過と同時に回復キューの増加が予想されます。 これは、可用性グループ データベースで多数の変更が突然行われた場合に予想されます。

復旧 (やり直し) キューを診断する方法

特定のセカンダリ レプリカ可用性グループ データベースの復旧キューを特定した後、セカンダリ レプリカに接続し、クエリを実行sys.dm_exec_requestsして復旧スレッドと wait_timewait_type決定します。 ループ内で実行できるクエリを次に示します。 1 つ以上の待機の種類の頻度が高く、それらの待機の種類の待機時間も探しています。 1 秒ごとに実行され、可用性グループ "agdb" の待機の種類と待機時間を報告するサンプル クエリを次に示します。

WHILE (1=1)
BEGIN
SELECT db_name(database_id) AS dbname, command, session_id, database_id, wait_type, wait_time,
os.runnable_tasks_count, os.pending_disk_io_count FROM sys.dm_exec_requests der JOIN sys.dm_os_schedulers os
ON der.scheduler_id=os.scheduler_id
WHERE command IN('PARALLEL REDO HELP TASK', 'PARALLEL REDO TASK', 'DB STARTUP')
AND database_id= db_id('agdb')
waitfor delay '00:00:05.000'
END

重要

意味のある待機の種類の出力の場合、この条件を監視するために前に説明したいずれかの方法を使用する場合、回復キューが増加していることを確認する必要があります。

この例では、一部の I/O 関連の待機の種類が報告されます (PAGEIOLATCH_UPPAGEIOATCH_EX)。 次の列で報告されているように、これらの待機の種類が引き続き最大値wait_timesを持っているかどうかを監視してチェックします。

次の列で報告される最大の待機時間を示すスクリーンショット。

やり直し待機の種類をSQL Serverする

待機の種類が特定されたら、2016/2017 SQL Server可用性グループのセカンダリ レプリカの再実行モデルとパフォーマンスに関する記事を参照してください。回復キューの原因となる一般的な待機の種類のクロスリファレンスとしてMicrosoft Tech Communityし、問題の解決に役立ちます。

セカンダリ レポート サーバー上のブロックされたやり直しスレッド

ソリューションがセカンダリ レプリカ上の可用性グループ データベースに対してレポート (クエリ) を指示する場合、これらの読み取り専用クエリはスキーマの安定性 (Sch-S) ロックを取得します。 これらの Sch-S ロックは、やり直しスレッドがスキーマ変更 (Sch-M) ロック ("スキーマ変更ロック" または LCK_M_SCH_Mとも呼ばれます) を取得するのをブロックして、または ALTER INDEXなどのALTER TABLEデータ定義言語 (DDL) の変更を行うことができます。 ブロックされたやり直しスレッドは、ブロックが解除されるまでログ レコードを適用できません。 これにより、復旧キューが発生する可能性があります。

ブロックされた再実行の履歴証拠をチェックするには、SSMS を使用してセカンダリ レプリカ上の AlwaysOn_health Xevent トレース ファイルを開きます。 イベントを探します lock_redo_blocked

ブロックされたやり直しの履歴証拠のチェックを示すスクリーンショット。

パフォーマンス モニターを使用して、回復キューへのブロックされたやり直しの影響をアクティブに監視します。 SQL Server::D atabase Replica::Redo blocked/sec および SQL Server::D atabase Replica::Recovery Queue カウンターを追加します。 次のスクリーンショットは、 ALTER TABLE ALTER COLUMN セカンダリ レプリカ上の同じテーブルに対して実行される実行時間の長いクエリ中に、プライマリ レプリカに対して実行されるコマンドを示しています。 Redo blocked/sec カウンターは、コマンドが実行されていることをALTER TABLE ALTER COLUMN示します。 実行時間の長いクエリがセカンダリ レプリカ上の同じテーブルで実行されている間、プライマリでそれ以降の変更が行われると、復旧キューが増加します。

スキーマ変更ロック待機の種類のモニターを示すスクリーンショット。

やり直しスレッドが取得しようとするスキーマ変更ロック待機の種類を監視します。 これを行うには、前に説明したクエリを使用して、に対するやり直し操作について報告される待機の種類をチェックしますsys.dm_exec_requests。 進行中のやり直しのブロックで、 の LCK_M_SCH_M 待ち時間が長くなっているのを確認できます。

LCK_M_SCH_Mの待機時間が長くなっていることを示すスクリーンショット。

シングル スレッドやり直し

SQL Server、Microsoft SQL Server 2016 でセカンダリ レプリカ データベースの並列復旧が導入されました。 SQL Microsoft Server 2012 または Microsoft SQL Server 2014 を実行するときに復旧キューが発生している場合は、プログラムの新しいバージョンにアップグレードして、運用環境での再実行パフォーマンスを向上させることができます。

シングル スレッドのやり直しは、並列復旧アーキテクチャが使用されるより高度なSQL Server バージョンでも発生する可能性があります。 これらのバージョンでは、SQL Server インスタンスでは、並列やり直しに最大 100 個のスレッドを使用できます。 プロセッサ数と可用性グループ データベースの数に応じて、並列再実行スレッドは最大 100 個の合計スレッドに割り当てられます。 100 スレッドの再実行制限に達すると、可用性グループ内の一部のデータベースに 1 つの再実行スレッドが割り当てられます。

可用性グループ データベースが並列復旧を使用しているかどうかを判断するには、セカンダリ レプリカに接続し、次のクエリを使用して、可用性グループ データベースの復旧を適用する行 (スレッド) の数を確認します。 次の例では、"agdb" データベースが 1 つのスレッドであり、そのコマンドが である場合、復旧ワークロードは DB STARTUP並列復旧の恩恵を受ける可能性があります。

SELECT db_name(database_id) AS dbname, command, session_id, database_id, wait_type, wait_time,
os.runnable_tasks_count, os.pending_disk_io_count FROM sys.dm_exec_requests der JOIN sys.dm_os_schedulers os
ON der.scheduler_id=os.scheduler_id
WHERE command IN ('PARALLEL REDO HELP TASK', 'PARALLEL REDO TASK', 'DB STARTUP')
AND database_id= db_id('agdb')

可用性グループ データベースが並列復旧を使用するかどうかを判断する方法を示すスクリーンショット。

データベースでシングル スレッドやり直しが使用されていることを確認する場合は、前述のアルゴリズムを確認して、SQL Serverが並列復旧専用の 100 個のワーカー スレッドの数を超えるかどうかを判断します。 このような状態は、"agdb" データベースが復旧に 1 つのスレッドのみを使用している理由である可能性があります。

SQL Server 2022 では、ワークロードに基づいてワーカー スレッドが並列復旧用に割り当てることができるように、新しい並列復旧アルゴリズムが使用されるようになりました。 これにより、ビジー状態のデータベースがシングル スレッドの復旧に残る可能性がなくなります。 詳細については、「Always On可用性グループの前提条件、制限、推奨事項」の「可用性グループ別のスレッド使用量」セクションを参照してください。