私は次のように4ノードAGセットアップを持っています。
すべてのノードのVMハードウェア構成:
- Microsoft SQL Server 2017 Enterprise Edition(RTM-CU14)(KB4484710)
- 16個のvCPU
- 356 GB RAM(これまでの話...)
- 最大並列度:1(アプリベンダーの要求に応じて)
- 並列処理のコストしきい値:50
- 最大サーバーメモリ(MB):338944(331 GB)
AG構成:
- ノード1:プライマリまたは同期コミット読み取り不可セカンダリ、自動フェイルオーバー用に構成
- ノード2:プライマリまたは同期コミット、読み取り不可のセカンダリ、自動フェイルオーバー用に構成
- ノード3:読み取り可能なセカンダリセット、非同期コミット、手動フェイルオーバー用に構成
- ノード4:非同期のコミットを備えた読み取り可能なセカンダリセット、手動フェイルオーバー用に構成
問題のクエリ:
このクエリについては、まったくおかしなことは何もありません。アプリケーション内のさまざまなキューにある未解決の作業項目の概要を提供します。以下の実行プランのリンクの1つからコードを確認できます。
プライマリノードでの実行動作:
プライマリノードで実行した場合、実行時間は通常約1秒です。以下は実行計画です。以下は、プライマリノードからのSTATISTICS IOおよびSTATISTICS TIMEからキャプチャされた統計です。
(347 rows affected)
Table 'Worktable'. Scan count 647, logical reads 2491, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'workitemlc'. Scan count 300, logical reads 7125, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'schedulertask'. Scan count 1, logical reads 29, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'wfschedulertask'. Scan count 1, logical reads 9, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'schedulerservice'. Scan count 1, logical reads 12, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'schedulerworkerpool'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'itemlc'. Scan count 1, logical reads 26372, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row affected)
SQL Server Execution Times:
CPU time = 500 ms, elapsed time = 656 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
読み取り専用セカンダリノードでの実行動作:
読み取り専用のセカンダリノード(ノード3またはノード4)で実行する場合、このクエリは同じ実行プラン(これは別のプランリンクです)を使用し、ほぼ同じ実行統計が表示されます(たとえば、さらにいくつかのページがある場合があります)スキャンはこれらの結果が常に変化するため)、CPU時間を除いて、非常によく似ています。以下は、読み取り専用のセカンダリノードからSTATISTICS IOおよびSTATISTICS TIMEからキャプチャされた統計です。
(347 rows affected)
Table 'Worktable'. Scan count 647, logical reads 2491, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'workitemlc'. Scan count 300, logical reads 7125, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'schedulertask'. Scan count 1, logical reads 29, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'wfschedulertask'. Scan count 1, logical reads 9, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'schedulerservice'. Scan count 1, logical reads 12, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'schedulerworkerpool'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'itemlc'. Scan count 1, logical reads 26372, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row affected)
SQL Server Execution Times:
CPU time = 55719 ms, elapsed time = 56335 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
その他の情報:
また、このクエリの実行中にセカンダリsp_WhoIsActive
と両方でPaul RandalのWaitingTasks.sql
スクリプトを実行しましたが、待機がまったく発生していないため、率直にイライラします。
同期ステータスは実際には非常に良好であるため、これはAGレイテンシの場合にも見えません。
--https://sqlperformance.com/2015/08/monitoring/availability-group-replica-sync
SELECT
ar.replica_server_name,
adc.database_name,
ag.name AS ag_name,
drs.is_local,
drs.synchronization_state_desc,
drs.synchronization_health_desc,
--drs.last_hardened_lsn,
--drs.last_hardened_time,
drs.last_redone_time,
drs.redo_queue_size,
drs.redo_rate,
(drs.redo_queue_size / drs.redo_rate) / 60.0 AS est_redo_completion_time_min,
drs.last_commit_lsn,
drs.last_commit_time
FROM sys.dm_hadr_database_replica_states AS drs
INNER JOIN sys.availability_databases_cluster AS adc
ON drs.group_id = adc.group_id AND
drs.group_database_id = adc.group_database_id
INNER JOIN sys.availability_groups AS ag
ON ag.group_id = drs.group_id
INNER JOIN sys.availability_replicas AS ar
ON drs.group_id = ar.group_id AND
drs.replica_id = ar.replica_id
ORDER BY
ag.name,
ar.replica_server_name,
adc.database_name;
このクエリは最悪の犯罪者のようです。プライマリノードで1秒未満かかる他のクエリは、セカンダリノードで1〜5秒かかる場合があります。動作はそれほど深刻ではありませんが、問題を引き起こしているようです。
最後に、サーバーも調べて、A / Vスキャンなどの外部プロセス、予期しないI / Oを生成する外部ジョブなどがないかを確認しました。これは、SQL Serverプロセス以外の原因が原因ではないと思います。
質問:
私がいるのは正午だけで、すでに長い日だったので、ここで明らかな何かを見逃しているのではないかと思います。それか、設定に誤りがあります。これは、この環境に関連するベンダーとMSへの呼び出しが何度もあったために発生する可能性があります。
私の調査のすべてについて、私はこのパフォーマンスの違いを引き起こしているものを見つけることができないようです。セカンダリノードで何らかの待機が発生することを期待しますが、何も発生しません。これをトラブルシューティングして根本的な原因を特定するにはどうすればよいですか?誰かが以前にこの動作を見て、それを解決する方法を見つけましたか?
更新#1
3番目のノード(読み取り専用レプリカの1つ)の状態を読み取り不可に交換してから、テストとして読み取り可能に戻した後、そのレプリカは開いているトランザクションによって引き続き保留されており、クライアントクエリはHADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING
待つ。
DBCC OPENTRAN
コマンドを実行すると、次の結果が得られます。
Oldest active transaction:
SPID (server process ID): 420s
UID (user ID) : -1
Name : QDS nested transaction
LSN : (941189:33148:8)
Start time : May 7 2019 12:54:06:753PM
SID : 0x0
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
このSPIDをで検索すると、コマンドとしてリストされてsp_who2
いるBACKGROUND
プロセスQUERY STORE BACK
として表示されます。
TLogバックアップをとることはできますが、この解決されたバグと同様の機能が実行されていると思われるため、本日、この特定の問題についてMSでチケットを開く予定です。
そのチケットの結果に応じて、Joeの提案に従ってコールスタックトレースをキャプチャして、どこに行くかを確認します。
最終更新(問題の自己解決)
(上記のように)開いているクエリストアトランザクションの52時間のマークを超えた後、AGは自動的にフェールオーバーすることを決定しました。これが発生する前に、追加のメトリックをいくつか取得しました。Seanによって提供されたこのリンクによれば、問題のデータベースには、このデータベース専用の非常に大きなバージョンストアがありました。特に、ある時点で、reserved_page_count
フィールドに1651360ページ、reserved_space_kb
値に13210880を記録しました。
エラーログごとに、フェールオーバーがに関連するトランザクション硬化障害の5分の大洪水後に発生したQDS base transaction
とQDS nested transaction
の取引。
私の場合、フェイルオーバーによって約10分の停止が発生しました。データベースのサイズは〜6TBで、非常にアクティブであるため、実際にはかなり良いと思いました。この間、新しいプライマリノードはオンラインでしたが、すべてが待機QDS_LOADDB
タイプで待機していたため、クライアントクエリを完了できませんでした。
フェイルオーバー後、バージョンストア番号はの176 reserved_page_count
と1408に減少しましたreserved_space_kb
。セカンダリ読み取り専用レプリカに対するクエリも、プライマリから実行された場合と同じように迅速に実行され始めたため、フェイルオーバーの結果、動作が完全に消えたように見えます。
QDS_LOADDB
ですが、将来的にそれを回避したいがクエリストアをオンにしたい場合は、マイクロソフトが推奨するこれらのトレースフラグを使用できます。特に7752では、クエリストアが初期化される前にクエリを実行できます(そのため、一部のクエリを見逃す可能性がありますが、データベースは稼働しています)。
7752
は特に便利です。先端をありがとう!