まとめ
この記事は、SQL Server Always On 可用性グループ内のセカンダリ レプリカでの回復キュー (再実行キューとも呼ばれます) のトラブルシューティングに役立ちます。 回復キューとは何か、再実行キューのサイズと再実行率を確認する方法、値を解釈する方法、Redo 遅延の一般的な原因 (ブロックされた再実行スレッドやシングル スレッドの再実行など) を診断して修正する方法について説明します。
復旧キューイングとは
可用性グループ データベースのプライマリ レプリカに加えられた変更は、同じ可用性グループ内のすべてのセカンダリ レプリカに送信されます。 変更がセカンダリ レプリカに到着すると、まず可用性グループ データベースのトランザクション ログ ファイルに書き込まれ(ハード化され)ます。 Microsoft SQL Server、recovery または redo 操作を使用して、これらのログ レコードをデータベース ファイルに適用します。
変更が再実行されるよりも速くトランザクション ログに到着して永続化されると、復旧キューが発生します。 このキューは、データベースにまだ適用されていない、強化されたログ レコードのセットです。
回復キューイングの症状と影響
セカンダリ レプリカの古いデータ
セカンダリ レプリカにクエリを実行する読み取り専用ワークロードでは、古いデータが取得される可能性があります。 復旧キューが発生した場合、同じデータに対してクエリを実行しても、プライマリ レプリカ データベースの最近の変更はセカンダリにまだ表示されません。
変更はセカンダリに到着し、データベース ログ ファイルに書き込まれますが、再実行によってデータ ファイルに適用されるまでは読み取りできません。
詳細については、「Always On 可用性グループの可用性モードの違い」のセカンダリ レプリカでの Data 待機時間に関するセクションを参照してください。
フェールオーバー時間の延長または RTO の超過
目標復旧時間 (RTO) は、組織が許容できるデータベースの最大ダウンタイムであり、停止後に組織がデータベースの使用を回復できる速度です。 フェールオーバーが発生したときにセカンダリ レプリカに大規模な復旧キューが存在する場合、新しいプライマリでの再実行に RTO よりも長い時間がかかる場合があります。 やり直しが完了すると、データベースはプライマリ ロールに移行し、フェールオーバー前に存在していた状態を反映します。 やり直し時間が長いほど、運用環境の再開速度が遅れます。
診断ツールが異常な可用性グループを報告する
再実行キューが重要な場合、SQL Server Management Studio (SSMS) の Always On ダッシュボードに、可用性グループが異常として表示されることがあります。
復旧キューの確認
復旧キューは、データベースごとの測定値です。 プライマリ レプリカの Always On ダッシュボードから、またはプライマリ レプリカまたはセカンダリ レプリカの sys.dm_hadr_database_replica_states 動的管理ビュー (DMV) に対してクエリを実行して確認できます。 パフォーマンス モニター カウンターでは、回復キューのサイズと再実行率も報告されます。 セカンダリ レプリカでこれらのカウンターを確認します。
次のいくつかのセクションでは、可用性グループ データベース復旧キューをアクティブに監視する方法について説明します。
sys.dm_hadr_database_replica_states に対してクエリを実行する
sys.dm_hadr_database_replica_states DMV は、可用性グループ データベースごとに 1 行を報告します。
redo_queue_size列には、回復キューのサイズがキロバイト単位で表示されます。 30 秒ごとに回復キュー サイズの傾向を監視するには、次のようなクエリを設定します。 プライマリ レプリカで実行します。
is_local=0 と redo_queue_size が関連するセカンダリ レプリカのデータを報告するには、redo_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
出力は次のようになります。
Always On ダッシュボードで回復キューを確認する
回復キューを確認するには、次の手順に従います。
SSMS オブジェクト エクスプローラーで、可用性グループを長押し (または右クリック) してコンテキスト メニューを開きます。
ダッシュボードを表示 を選択します。
可用性グループ データベースは最後に一覧表示され、データベースごとに一部のデータが報告されます。 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 秒ごとに自動更新します。
パフォーマンス モニターで回復キューを確認する
各セカンダリ レプリカとデータベースには、独自の回復キュー サイズがあります。 可用性グループ データベースの復旧キューを確認するには、次の手順に従います。
セカンダリ レプリカでパフォーマンス モニターを開きます。
追加 (カウンター) ボタンを選択します。
[ 使用可能なカウンター] で、[SQLServer:Database Replica] を選択し、[ 回復キュー ] カウンターと [ 再実行バイト数/秒 ] カウンターを選択します。
Instance リスト ボックスで、復旧キューを監視する可用性グループ データベースを選択します。
[追加]>[OK] の順に選択します。
復旧キューイングの増加は、次のように見える場合があります。
復旧キューの値を解釈する
このセクションでは、前のセクションで収集した回復キューの値を解釈する方法について説明します。
回復処理のキューイングが問題になる場合
回復キューの値 が 0 の場合は、レポートの時点で再実行バックログがないことを意味します。 高負荷の本番環境では、可用性グループが正常な場合でも、回復キューは 0 以外の値を示すことがよくあります。 一般的な運用環境では、値が 0 から 0 以外の値の間で変動することを想定します。
復旧キューが時間の経過と共に増加する場合は、さらに調査します。 増加は、何かが変更されたことを示します。 急激な増加が見た場合は、次の測定値がトラブルシューティングに役立ちます。
- ログ再実行率 (KB/sec) (Always On ダッシュボード)
-
redo_rateのsys.dm_hadr_database_replica_states
ベースライン復旧率を確立する
Always On が正常に稼働している間は、高負荷の可用性グループ データベースの REDO 速度を監視してください。 大規模なトランザクション (インデックスの再構築や ETL プロセスなど) がスループットを向上させる場合の、一般的な営業時間中およびメンテナンス期間中のキャプチャ レート。 復旧キューの増加が確認されたら、これらのベースラインを比較して、何が変更されたかを特定します。 ワークロードが通常よりも大きい場合や、やり直し率が予想よりも低い場合があり、さらに調査する必要があります。
ワークロード量を考慮する
大規模なワークロード (100 万行に対する UPDATE ステートメント、1 TB のテーブルでのインデックスの再構築、数百万行を挿入する ETL バッチなど) では、通常、復旧キューがすぐにまたは時間の経過と同時に増加します。 可用性グループ データベースで多数の変更が突然行われると、この増加が予想されます。
回復のキュー処理を診断する
特定のセカンダリ レプリカ可用性グループ データベースの復旧キューを特定した後、セカンダリ レプリカに接続し、 sys.dm_exec_requests クエリを実行して、復旧スレッドの wait_type と wait_time を確認します。 探すべきなのは、1 種類以上の待機タイプが高い頻度で発生しており、それらの待機タイプの待機時間が長いことです。 次のサンプル クエリは 5 秒ごとに実行され、可用性グループ データベースの 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_UP、 PAGEIOLATCH_EX)。 次の列で報告されているように、これらの待機の種類で最大の wait_time 値が引き続き表示されるかどうかを監視します。
復旧待機の種類を特定する
待機の種類を特定したら、 可用性グループのセカンダリ レプリカの再実行モデルとパフォーマンス を、復旧キューの原因となる一般的な待機の種類と、問題の修正方法に関するガイダンスのクロスリファレンスとして使用します。
読み取り専用セカンダリ レプリカでの回復スレッドのブロック
ソリューションがセカンダリ レプリカ上の可用性グループ データベースに対してレポート (クエリ) を実行する場合、それらの読み取り専用クエリはスキーマの安定性 (Sch-S) ロックを取得します。 Sch-S ロックでは、再実行スレッドが、LCK_M_SCH_MやALTER TABLEなどのデータ定義言語 (DDL) の変更を適用するために必要なスキーマ変更 (Sch-M) ロック (スキーマ変更ロック、またはALTER INDEXとも呼ばれます) を取得するのをブロックできます。 ブロックされた再実行スレッドは、ブロックが解除されるまでログ レコードを適用できないため、復旧キューが発生します。
ブロックされた再実行の履歴証拠を確認するには、SSMS を使用してセカンダリ レプリカ上 のAlwaysOn_health 拡張イベント トレース ファイルを開きます。
lock_redo_blockedイベントを探します。
パフォーマンス モニターを使用して、回復キューに対するブロックされた再実行の影響を積極的に監視します。
SQL Server:Database Replica\Redo blocked/sec カウンターと SQL Server:Database Replica\Recovery Queue カウンターを追加します。 次のスクリーンショットは、セカンダリ レプリカ上の同じテーブルに対して実行時間の長いクエリが実行されている間に、プライマリ レプリカに対して実行される ALTER TABLE ALTER COLUMN コマンドを示しています。
Redo blocked/sec カウンターは、ALTER TABLE ALTER COLUMN コマンドを実行すると急上昇します。 実行時間の長いクエリがセカンダリ レプリカ上の同じテーブルでアクティブになっている間、プライマリに対する後続の変更によって復旧キューが増加します。
REDO スレッドが取得しようとするスキーマ変更ロックの待機タイプを監視します。 前のクエリを使用して、 sys.dm_exec_requestsでの再実行操作について報告された待機の種類を確認します。 再実行がブロックされている間、LCK_M_SCH_M の待機時間が増えるのを確認できます。
単一スレッド復旧
SQL Server 2016 では、セカンダリ レプリカ データベースの並列復旧が導入されました。 SQL Server 2014 や SQL Server 2012 など、以前のバージョンを実行している場合は、サポートされているバージョンにアップグレードして、並列再実行を行い、再実行のパフォーマンスを向上させます。
シングル スレッド再実行は、並列復旧アーキテクチャを使用する SQL Server 2016 ~ SQL Server 2019 で引き続き発生する可能性があります。 これらのバージョンでは、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 可用性グループの前提条件、制限、および推奨事項」の「 可用性グループ別のスレッド使用量 」セクションを参照してください。