最近、SQLサーバー2008から新しいサーバーにアップグレードし、SQLサーバー2016(SP1 CU3)にアップグレードしました
新しいサーバーハードウェアhp proliant 580G8、4ソケットインテルxeon E7プロセッサー、合計60コア、640GB ram、8インテルSSD S3700 RAID 10、ローカル
環境はビジーですOLTP約3Kのバッチリクエスト/秒のシステムで、ほとんどが挿入され、更新の程度は低くなります。OLTPシステムの場合、ほとんどが1つの挿入です/ transactionトランザクションのコミットがたくさんあります。システムの目的でいくつかのレポートクエリがあります(キューリーダー、監視など)
問題は、ログのフラッシュのパフォーマンスが遅く、書き込みログの待機が発生することです。私はI/Oをテストしましたが、4kランダム書き込みテストで100K iops /秒以上、2500MB /秒までの順次書き込みを管理できます
データベースの互換性レベル= 130(SQLサーバー2016)
間接チェックポイント=オン、
VLFカウント= 80-120
プロセッサCPU使用率3%-8%、平均5%、ログバックアップの実行時に最大10%未満(圧縮バックアップ)合計信号時間/合計待機時間= 6%-94%リソース待機時間
メモリーPLEは毎秒刻み目をつけようとしています。現在は584000秒を表しており、ページスワップはほとんど観測されません(ページ/秒)。
これは私が見つけた本当の問題です
「ログフラッシュ/秒」= 1000〜2000 /秒
「ログフラッシュ待機時間」= 1000〜4000ミリ秒/秒
「ログフラッシュ書き込み時間」= 10〜15 ms/secのスパイクで0〜1 ms/sec
"AVG disk sec/write" = 0
「現在のディスクキュー」= 0(数分ごとに2のスパイク)
「ディスクアイドル時間」= 90%-100%
sQLサーバーはSSDアレイが提供する超低遅延を使用できないため、何か問題があるようです...
私はCPUアフィニティマスクからログライタースレッドを無効にしようとしましたが、クリスアドキンは成功せずにブログに書き込みました。また、拡張イベントを使用してログフラッシュを監視し、1回のログフラッシュで複数の待機が発生するのを見ました。
以前のサーバーにこの問題が存在するかどうかはわかりません。そのプラットフォームでは、I/Oがちょっと問題で、「ログフラッシュの書き込み時間」がかなり長くなっていたためです...
現場でこの問題を見たことがありますか。今後の解決策は何ですか。
これは「これからの解決策は何ですか」に対する答えではなく、問題を特定する方法の詳細です。
トランザクションログは、ディスクにどのように強化されるかという点では、データページとは異なります。トランザクションログは最初にログバッファーに書き込まれ、次に非同期的にディスクに書き込まれます。 2016では、各データベースのトランザクションログに対して同時に実行できるログフラッシュI/Oは112に制限されています。
SQL Serverがログバッファーをディスクに(トランザクションログ内の隣接するログブロックに)フラッシュする必要がある原因は3つあります。
最小のログフラッシュは、単一の512バイトのログブロックです。ワークロード内のすべてのトランザクションが非常に小さい場合(単一の小さなテーブル行を挿入するなど)、最小サイズのログフラッシュが多数発生します。適切なトランザクションログのスループットを可能にするために、ログのフラッシュは非同期で実行されますが、一度に112の同時ログフラッシュI/Oの固定制限があります。
あなたが説明したように、多数の短いトランザクション/秒と組み合わせた優れたioサブシステムがあり、問題が続いている可能性があります。
高性能のI/Oサブシステムでは、書き込みが非常に速く完了する場合がありますが、ログフラッシュの同時I/Oが112に制限されているため、ログレコードをディスク上で永続的にしようとするとボトルネックが生じます。この状況は、sys.dm_io_pending_io_requestsの集約された出力で、低い書き込みレイテンシと112に近いほぼ一定の未解決のトランザクションログ書き込みによって識別できます。
上記のほとんどは以下のリソースからのものであり、説明されているソリューションはほとんどありません。また、Paul Randalには、上記の問題が発生しているかどうかを確認するためのデモスクリプトを含む短いビデオがあります。
(回答ではありませんが、コメントはコードを許可しません。)
AlwaysOn AGもミラーもありませんよね?
ユーザーデータベースで、次のように最大ログフラッシュ率をテストします。
create table t(id int)
go
set nocount on
declare @i int = 0
while @i < 100000
begin
insert into t(id) values (@i);
set @i = @i + 1;
end