SQL Server DBは夜間に使用できなくなります


9

昨日、私のSQL Serverデータベースは大丈夫でした。今日はほとんど使用できません-いつ攻撃したかによって、5から20倍の速度で減速します。

一部のデータは夜間のロードプロセスでサーバーに追加されましたが、データベースにそれほど影響を与えるはずのボリュームのようなものはありません。約50,000のプレーンテキストレコード(XMLやその他のフリッパーなし)。

今朝サーバーをリブートする前にパッチを当てました。ただし、パッチが適用された他のデータベースサーバーは、動作が異なります。

リソースモニターは、ディスクIOに問題があることを示唆しているようです。.mdfファイルの容量のほぼ100%で、データベースで実際にほとんど発生していない場合でも、常に実行されています。Templog.ldfへのアクセスも非常に高くなっています。

ここには誰もエキスパートDBA(私たちはSQLスキルの量がさまざまな開発者です)は誰もいません。私たちは、sp_updatestatsを実行して、大きなインデックスのいくつかを別のディスクに移動しようとしましたが、役に立ちませんでした。

私はこれがパッチと関係があるに違いないと思います-それはあまりにも多くの偶然のようです。同僚は、mdfのサイズを増加させる原因となったデータ負荷が、実行計画の非効率化の原因となったと確信しています。

これは一体何が原因ですか?どのようにしてそれを見つけ出し、それを修正するために何ができるでしょうか?

編集:

を使用しsp_WhoIsActiveても、異常なことは何も明らかにされません。自分のsprocの使用と、現在別のインデックスを移動しようとしている同僚からのいくつかのコマンドを登録します。それはおそらく現在DBを保持していますが、以前と同じように実行されていませんでした。

SQL Server 2008 R2の標準バージョンです。SELECT @@VERSION与える:

Microsoft SQL Server 2008 R2(SP2)-10.50.4033.0(X64)
2014年7月9日16:04:25
Copyright(c)Microsoft Corporation Standard Edition(64-bit)on Windows NT 6.1(Build 7601:Service Pack 1)(Hypervisor )

サーバーには、72GBのRAMと3つのクアッドコア2GHzプロセッサーが搭載されています。

パッチはWindowsにのみ適用されました。パッチ以外の変更はありませんでした。

選択した設定:

_id     name                        value   minimum     maximum     value_in_use    description                                 is_dynamic  is_advanced
1540    min memory per query (KB)   1024    512         2147483647  1024            minimum memory per query (kBytes)           1           1
1541    query wait (s)              -1      -1          2147483647  -1              maximum time to wait for query memory (s)   1           1
1543    min server memory (MB)      0       0           2147483647  16              Minimum size of server memory (MB)          1           1
1544    max server memory (MB)      65536   16          2147483647  65536           Maximum size of server memory (MB)          1           1

更新:インデックスとテーブルを別のディスクパーティションにシフトすると、状況が改善されるようです。どのようにして私たちが転換点に到達できたのか、そのような劇的な結果で突然突然混乱します。


sp_whoisactiveを5分間実行して、出力をテーブルにキャプチャできますか?あなたはからダウンロードすることができ、ここ、これはあなたがテーブルに出力をキャプチャすることができますどのように表示されます
キン・シャー

サーバーを再起動した場合、つまり、キャッシュされたすべてのデータがバッファープールからダンプされ、キャッシュされた実行プランもすべてダンプされました。つまり、SQL Serverは両方を強化する必要があります。すべての実行プランを再コンパイルする必要があり、統計が古い場合、最も効率的なプランを取得できない可能性があります。また、データはディスクからメモリに読み込まれる必要があることを意味しますが、再起動前はおそらくメモリ内のデータと一緒にハミングしていました。これは短命です。
アーロンバートランド

@AaronBertrandそれは8時間このようなものでした。パッチを適用するためにサーバーを定期的に再起動しますが、これまでこのようなことに気づいたことはありません。
Bob

1
UIを使用して構成設定を確認しないでください。SELECT * FROM sys.configurations;-あなたはのvalue, value_in_useようなものにしたいですmax server memory (MB)。また、SELECT @@VERSION;ハイパーバイザーにあるかどうか、昨日以降(または最後にSQL Serverを再起動した後)にホストで変更があったかどうかだけでなく、のビルド番号も役立ちます。
アーロンバートランド

2
どのタイプのIOサブシステムを使用していますか?SAN、ローカルディスクなど?ドライブが偶然故障した可能性はありますか?また、DBはOSファイルと同じ場所に保存されていますか?そして最後の質問。OSアップグレードを行う前のプロセスの一部は、事前にVMスナップショットを取得することでした。残念ながら責任者はそれをコミットするのを忘れていました。システム全体が急速に遅くなった。これがあなたに起こった可能性はありますか?
ケネスフィッシャー

回答:


3

少量のデータがSQL Serverの特定の制限に達して、別の計画などを強制することがあります。これはありそうなことではありません。しかし、あなたのディスクが重荷になっているように見えるという事実は、私を別の結論に導きます。

スローダウンには、2つの理由が考えられます。

  1. システムをアップグレードして再起動した
  2. そこに大量のデータをロードします

パート1を見てみましょう

SQL Server構成が壊れている可能性があります。これは、サーバーの速度とディスクの使用に関して深刻な問題を引き起こす可能性があります。

最初のインスタンスで基本的なサーバー設定を確認してください。これらの基本的な設定はmax server memoryaffinity I/O maskaffinity maskmax degree of parallelism。を使用して詳細オプションを有効にする必要がある場合がありますshow advanced options

以下は完全なスクリプトです。

-- enable advanced options
EXEC sp_configure 'show advanced options',1
-- apply configuration
RECONFIGURE
-- how much memory can the sql server allocate?
EXEC sp_configure 'max server memory'
-- which cpu is used to run I/O operations
EXEC sp_configure 'affinity I/O mask'
-- which cpus can run processes?
EXEC sp_configure 'affinity mask'
-- how many threads can work on one query part?
EXEC sp_configure 'max degree of parallelism'

結果をインストール手順で文書化された値と比較します。彼らはまだ同じですか?

サーバーの動作がおかしいのには多くの理由があります。私は通常あなたmax server memoryが間違っていることを賭けます。これにより、SQL Serverがデータページを永続的にスワップします。彼はすべてを記憶に留めることはできません。つまり、ディスクからページを読み取って更新し、すぐに書き戻す必要があります。別の更新が発生し、更新に同じページを使用する場合、メモリから読み取ることはできません。代わりに、サーバーはディスクから再度読み取る必要があります。交換するだけ...

別の問題は、ディスクまたはプロセスの親和性が非常に高い場合があります。共有サーバー(SQL Server +その他のサービス)とSQL Server専用のディスクを使用した場合(これはまれなケースですが、可能性があります)、これが問題になる可能性があります。サーバーは通常、たとえばプロセス用に3つのCPUとI / O用に1つ使用されていました。他の12 CPUは他のサービスに使用されます。この場合、アフィニティマスクが間違っており、たとえば自動構成を使用しています。これは、サーバーがプロセスとI / Oに動的に16コアすべてを使用することを意味します。実行中の巨大なプロセスがある場合、それらはディスクに大きな負荷をかける可能性があり、処理できない場合があります。しかし、実際には、これはあなたのケースだとは思いません。これが当てはまると(少しでも)より速くなりますが、あなたのケースは遅くなります。

もう1つの問題は、並列度が高すぎることです。つまり、クエリの1つの部分でアイドル状態になっているスレッドが多すぎます。また、並列処理が期待どおりに機能しない場合、これにより大幅なスローダウンが発生する可能性があります。しかし、これはあなたの高いI / Oを全体的に表すものではありません。

では、パート2も見てみましょう。

一連の行をシステムにロードします。これが通常のジョブであっても、クエリプランがエスカレートする制限が発生する可能性があります。SQL Serverと組み合わせて挿入すると、この動作が発生する場合もあります。

あなたはすでにインデックスを別のディスクに移行しようとしていると述べましたが、それは助けになりそうです。これは、負荷を2つの異なるディスクに分割したという事実によってのみ発生します。

インデックスがフラクチャした、プランがフラクチャした、または統計が古くなっている可能性があります。

1.統計の最終更新を確認します。 これは、単一の統計要素ごとにインターフェースを介して手動で実行できます。それは苦痛でしょう。または、このコードを試すことができます:

SELECT name AS indexname,
STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes

これにより、各インデックス(およびヒープ)とその背後にある統計に関する完全な情報が得られます。実行しsp_updatestatsても、統計が更新されたわけではありません。更新が非常にトリッキーである部分は、実行したsp_updatestats場合でも、auto update statistics有効になっている場合でも、統計は正確に更新されません。更新が必要/生成されたときのエッジポイントは次のとおりです。

  • 空のテーブルは1つ以上の行を取得します
  • 500行を超えるテーブルは、20%+ 500追加の行を更新し、その後挿入が発生しました
  • 500行未満のテーブルで500行が変更されたとき

つまり、更新を実行しても、統計が古くなっている可能性があります。

上記のクエリをご覧ください。一部のテーブルでかなり古い統計を見つけた場合は、このテーブルに対して手動で統計更新を実行することをお勧めします。

UPDATE STATISTICS dbo.YourBadTable WITH FULLSCAN

その後、古い計画をすべて破棄するために、サーバーでお尻を蹴ることができます。

DBCC FREEPROCCACHE 

すべてのキャッシュを消去したいだけなら、代わりにこれを実行したいかもしれません:

DBCC FREESYSTEMCACHE ('ALL')

これにより、プランキャッシュだけでなく、すべてのキャッシュがクリーンアップされます。私は通常、これを本番サーバーの本番フェーズで使用するように警告します。ただし、サーバーが現在動作していないため、サーバーにあまり害を及ぼすことはできません。彼はすべてのキャッシュを再構築する必要があるため、数秒から1〜2分程度遅くなる可能性がありますが、その後は正しい計画で実行する必要があります。

別の理由は、完全に断片化されたインデックスである可能性があります。これは、次のステートメントを使用してサーバー全体で確認できます。

SELECT * 
FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, NULL)

断片化が非常に高い場合は、再編成(断片化<20%)または完全に再構築(> 20%)する必要がある場合があります。これにより、ディスクにさらに圧力がかかり、問題が発生する可能性があります。一方、インデックスがそれほど悪い場合、それはおそらく害を及ぼすよりも最終的には役立つでしょう。

これらの2つの理由に加えて、3番目の問題がまだある可能性があります

サーバーが設定されている可能性があります。今回はコードを変更しておらず、数行追加しています。すべての統計が更新され、すべてのキャッシュが再構築されます。すべてのインデックスは、必要な方法で再編成されますが、何も機能しません。プロセスで使用可能なメモリの制限に達した可能性があります。多分あなたはもっと必要です。あなたが持っているよりも多くのメモリを取得しようとするプロセスがあるかどうかを簡単に確認できます。

次のコマンドを使用してこれを確認できます。

SELECT * FROM sys.dm_exec_query_memory_grants

メモリを消費するすべてのセッションのリストが表示されます。メモリを取得するためにまだ待機しているクエリがある可能性があります。これらのクエリは簡単にフィルタリングできます。すべてのセッションgranted_memory_kb IS NULL。これらは、メモリを要求したがそれを取得しなかったセッションです。もう1つは、メモリ不足になる可能性がある許可されたメモリです。列をrequested_memory_kbと比較できますgranted_memory_kb。要求された場合は、プロセスが最適に実行されるために必要なメモリ量が表示されますが、許可された場合は、プロセスで有効なメモリが表示されます。プロセスの実行に2GBが必要だが、2MBしか取得しない場合...自分でそれを取得する場合があります。;-)

もう1つの方法は、次を確認することRESSOURCE_SEMAPHOREです。

SELECT * FROM sys.dm_exec_query_resource_semaphore

あなたは見てとることができますwaiter_countgrantee_count。ウェイターが0より大きい場合、メモリに圧力がかかっているため、スワッピングが発生したり、perfmonでディスクに圧力がかかったりすることがあります。


0

考えられるドライブ障害に加えて、RAIDサブシステムの状態を確認します。似たようなものを確認したところ、RAIDコントローラーのバッテリーが故障しているため、書き込みキャッシュが利用できず、すべての書き込みを直接ディスクに書き込む必要がありました。片側注意-RDCがシステムに入る間、システムが一時停止するのを感じることができました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.