SqlExceptionのトラブルシューティングに役立ちます:接続でタイムアウトが期限切れになりました。非負荷状態の場合

StackOverflow https://stackoverflow.com/questions/1421978

質問

トラフィックがほとんどない私のWebサイトをホストしているサーバーがあります。
毎日数人(<!> lt; 20)がサイトにアクセスし、数人のRSSリーダーが私たちが公開したフィードを購読しています。

ほぼ毎晩、RSSリーダーは深夜に私たちを襲い、接続のタイムアウトのためにWebサイトがSQL Serverに接続できないという例外を受け取ります。 詳細は非常に奇妙なので、どこから探し始めればよいかわからないので、問題になる可能性のあるものについての助けを探しています。

ASP.Net MVC、Entity Framework、およびSQL Server 2008をWindows Server 2008上で使用しています。このマシンは、最上位ではないプロバイダーから入手した専用のボックスであるため、最適に設定されない可能性があります。誰が他に何を知っているか。
ボックスも非常に小さく、1Gb RAMしか搭載されていませんが、現在のような負荷がかかるはずです...

以下のコールスタック全体をコピーしていますが、まず、知っていることのいくつかを説明します。

  • このエラーは、iTunesが当社のサイトを照会しているときに常に発生します。これは何の関係もありませんが、真実はiTunesからしか取得できないということです。私の一番の推測は、誰も私たちに当たっていないその夜の時間にiTunesだけが私たちに問い合わせるので、これが起こるということです。
  • 私たちの理論の1つは、SQL ServerとIISがメモリを奪い合っており、そのうちの1つが使用されていないディスクからページングされており、誰かが<!> quot;ウェイクアップ<!> quot; 、ディスクからすべてをメモリに読み込むのに時間がかかりすぎます。これは潜在的に発生する可能性があるものですか? (可能であれば、SQL Serverの設計上の問題のように聞こえるので、これを破棄します)
  • EFエンティティを適切に破棄していない可能性があるため、接続がリークしている可能性についても考えました(こちらの質問をご覧ください)。これが問題をグーグルで見つけることができる唯一のものです。負荷が非常に低いため、これは破棄します。
  • これは常に夜間に発生するため、しばらくの間何も発生しなかったという事実に関連する可能性が非常に高くなります。たとえば、これらのリクエストがヒットすると、Webサーバープロセスがリサイクルされ、すべてが起動/再JITされることは間違いありません。ただし、再JITtingはSQLタイムアウトを説明しません。

更新:提案どおりプロファイラを添付しましたが、新しい例外が発生するまでにかなり時間がかかりました。これは私たちが知っている新しいものです:

  • プロファイラーを添付することで、非常にエラーが減少しました。実際、通常は1日に数回取得した後、これが1回発生するまで3〜4日待つ必要がありました。プロファイラーを停止すると、通常のエラー頻度に戻りました(さらに悪いことに)。そのため、プロファイラーには、この問題をある程度隠しているが、完全には隠していない何らかの効果があります。
  • IISリクエストログの横にあるプロファイラートレースを見ると、リクエストとクエリの間に予想される1-1の対応があります。しかし、時々、IISログとはまったく関係のないクエリが大量に実行されています。実際、実際のバグが記録される直前に、 3分間で750件のクエリが得られましたが、これらはすべてIISログとはまったく関係ありませんでした。クエリテキストは、EFが生成する読み取り不可能な種類のように見えますが、すべて同じではなく、Webサイトからのクエリのように見えます。同じApplicationName、Userなど。つまり、サイトは、 2日間
  • の間に、DBにヒットする約370のIISリクエストを受け取りました。
  • これらの説明されていないクエリは、以前のウェブサイトのものと同じClientProcessIDからのものではありませんでしたが、ウェブサイトからのものであった可能性がありますe、その間にプロセスがリサイクルされた場合。最後に説明されたクエリと最初の説明されていないクエリの間に、ほぼ1時間アクティビティがありませんでした。
  • これらがどこから来たのかわからないクエリのこれらの長い縞の1つは、エラーがログに記録される直前に来たので、これが私たちが従うべき手がかりだと思います。
  • 当初予想していたように、エラーをスローしたクエリが実行されたとき、それは前のものとは異なるClientProcessIDからのものでした(前の説明されていないものから8分後、前のIISのものよりほぼ正確に1時間後) )。これは、私にとって、ワーカープロセスが実際にリサイクルされたことを意味します。
  • これは私が絶対に理解していないものです。 IISログは、エラーリクエストの1分前に4が完全に処理されたことを示していますが、それらのクエリはトレースにまったく表示されません。実際、4つがうまくいった後、すぐに4つの例外がスローされましたが、これら4つの例外もトレースに表示されません(接続にタイムアウトがあった場合、クエリは実行されなかったはずなので、しかし、トレースにも接続試行が表示されません)

つまり、要するに、私はこれについて完全に無知です。数百件のクエリが連続して実行される理由を見つけることはできませんが、それらは問題に関係しているに違いないと考えています。
接続の問題を診断する方法もわかりません...
または、プロファイラーのトレースに、IISによると正常に処理されたクエリが欠落している可能性があります...

アイデアはありますか


これは例外情報です:

System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

System.Data.EntityException: The underlying provider failed on Open. ---> System.Data.SqlClient.SqlException: Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
   at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
   at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.SqlClient.SqlConnection.Open()
   at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
   at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
   --- End of inner exception stack trace ---
   at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
   at System.Data.EntityClient.EntityConnection.Open()
   at System.Data.Objects.ObjectContext.EnsureConnection()
   at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
   at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
   at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__1[TResult](IEnumerable`1 sequence)
   at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
   at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression)
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
   at MyProject.Controllers.SitesController.Feed(Int32 id) in C:\...\Controller.cs:line 38
   at lambda_method(ExecutionScope , ControllerBase , Object[] )
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.ExecuteCore()
   at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

どんなアイデアも大歓迎です。

役に立ちましたか?

解決

メモリ不足

これはメモリの問題である可能性が高く、おそらく他の要因によって悪化またはトリガーされますが、それでも本質的にメモリの問題です。他にも2つの(可能性は低い)可能性があります。最初に確認して削除する必要があります(そうするのは簡単だからです):

可能性を確認するのは簡単:

  1. <!> quot; Auto Close <!> quot;有効:自動クローズはまさにこの動作を持つことができますが、オンにすることはまれです。これを確認するには、SSMSでアプリケーションデータベースを右クリックし、<!> quot; Properties <!> quot;を選択してから、<!> quot; Options <!> quot;を選択します。ペイン。 <!> quot; Auto Close <!> quot;を見てください。入力し、Falseに設定されていることを確認します。 tempdbも確認してください。

  2. SQLエージェントジョブが原因である可能性があります。イベント中に一貫して実行されているジョブがあるかどうか、エージェントの履歴ログを確認します。インデックスの再構築などは、実行中のパフォーマンスの問題として頻繁に引用されるため、メンテナンスジョブも必ず確認してください。これらは、プロファイラの影響を通常受けないという理由だけで、今ではありそうもない候補です。

メモリの問題のように見える理由:

何も表示されない場合は、メモリの問題を確認する必要があります。私はあなたの場合の原因としてメモリを疑います:

  • 1 GBのメモリがあります:これは技術的にはSQL Serverの最小値を上回っていますが、SQL Serverの推奨値をはるかに下回り、私の経験では、たとえわずかでもロードされたサーバー。

  • IISとSQL Serverを同じボックスで実行しています:これは、メモリの競合が原因であることが主な理由ですが、IISでは1 GBのメモリしか使用できないため、これ自体はお勧めできません。アプリ、SQL Server、OS、その他のタスクおよび/またはメンテナンスはすべて非常に少ないメモリで戦っています。 Windowsがこれを管理する方法は、アクティブでないプロセスから積極的にメモリを削除することにより、アクティブなプロセスにメモリを提供することです。 SQL Serverなどの大規模なプロセスがこの状況でリクエストを完全に処理できるように十分なメモリを取り戻すには、数秒または数分かかる場合があります。

  • プロファイラーは、問題の90%を解消しました。これは、メモリが問題である可能性が高いことを示す大きな手掛かりです。常に少しビットだけアクティブです。多くの場合、これはOSの<!> quot; scavenger <!> quot;を回避するのに十分なアクティビティです。リスト、または少なくともその影響をいくらか軽減します。

原因としてメモリをチェックする方法:

  1. プロファイラーをオフにする:問題にハイゼンベルグ効果があるため、オフにする必要があります。オフにしないと、問題を確実に確認できません。

  2. 別のボックスからシステムモニター(perfmon.exe)を実行し、SQL ServerとIISが実行されているボックスのパフォーマンスコレクションサービスにリモートで接続します。最初に3つのデフォルトの統計情報(ローカルのみ)を削除し、次に必要な統計情報(以下)を追加することでこれを最も簡単に行うことができますが、最初のドロップダウンのコンピューター名を変更してSQLに接続してください

  3. <!> quot; Counter Log <!> quot;を作成して、収集したデータをファイルに送信します。 perfmonで。これに慣れていない場合、最も簡単な方法は、おそらく、Excelで開いて分析できるタブまたはコンマ区切りファイルにデータを収集することです。

  4. perfmonを設定してファイルに収集し、次のカウンターをファイルに追加します。

    -Processor \%Processor Time [Total]

    -PhysicalDisk \%アイドル時間[各ディスク]

    -PhysicalDisk \ Avg。ディスクキューの長さ[各ディスク]

    -Memory \ Pages / sec

    -Memory \ Page読み取り/秒

    -Memory \ Available MBytes

    -Network Interface \ Bytes Total / sec [使用中の各インターフェイス]

    -Process \%Processor Time [以下を参照]

    -Process \ Page Faults / sec [以下を参照]

    -Process \ Working Set [以下を参照]

  5. Processカウンター(上記)には、sqlserver.exeプロセス、IISプロセス、および安定したアプリケーションプロセスを含める必要があります。これは<!> quot; stable <!> quotに対してのみ機能することに注意してください。プロセス。必要に応じて継続的に再作成されるプロセスは、存在する前に指定する方法がないため、この方法でキャプチャすることはできません。

  6. 問題が最も頻繁に発生する時間帯に、このコレクションをファイルに対して実行します。収集間隔を10〜15秒に近い値に設定します。 (これにより多くのデータが収集されますが、個別のイベントを選択するにはこの解像度が必要になります)。

  7. 1つ以上のインシデントが発生したら、収集を停止し、収集したデータファイルをExcelで開きます。おそらく、タイムスタンプ列を表示しやすくするために再フォーマットし、時間、分、秒を表示する必要があります。 IISログを使用してインシデントの正確な時間を特定し、perfmonデータを調べて、インシデントの前後に何が起こっていたかを確認します。特に、作業セットが前に小さく、後に大きくなり、その間に多くのページフォールトが発生するかどうかを確認します。これがこの問題の最も明確な兆候です。

ソリューション:

IISとSQL Serverを2つの異なるボックスに分割するか(推奨)、ボックスにメモリを追加します。 3〜4 GBが最低だと思います。

その奇妙なEFスタッフはどうですか?

ここで問題となるのは、主な問題の周辺またはほとんどの原因である可能性が高いことです。プロファイラーはインシデントの90%を消滅させたため、残っているものは 別の問題かもしれませんし、問題の最も極端な aggravator かもしれません。その振る舞いのため、キャッシュを循環させているか、アプリケーションサーバープロセスのバックグラウンドメンテナンスが他にあるのでしょうか。

他のヒント

タイムアウトのタイムスタンプを夜間バックアップの実行時間と比較します。それらが一致する場合、RSSフィードをその間静的に設定できます。

(正確な答えではありませんが)試すべきもう1つのことは、すぐに sp_who タイムアウト例外が発生したとき。すべてをキャッチするわけではありません(これを実行するまでに問題のプロセスを実行できる可能性があります)が、幸運になるかもしれません。

また、夜に帰宅したときにSQLプロファイラを起動し、エラーが再度表示された場合は翌朝にアクティビティを実行することもできます。サーバー自体からは実行しないでください(起動時にこのことを思い出すと確信しています)。

編集:アップデートの対処。

EFはキャッシュを更新/作成していますか?一度に豊富なクエリと、後にデータベースにヒットするクエリがない理由を説明できます。

それ以外は、ヘイゼンバグがあるようです。追加できると思うのは、(ファイルまたはイベントログへの)より多くのログを記録することだけです。

それは、同時に実行されるクロン化されたものの匂いがします。 RBarryYoungが言っているように..毎晩のバックアップか、何か別のものである可能性があります サーバーへのルートアクセスがありますか? crontabが見えますか?

問題が発生している時間の近くでインデックスの再作成手順を実行するのは、SQLサーバー上にあるフルテキストインデックスプラグインですか?

私の場合、sqlserver 2008 r2 sp3をインストールすると、問題はなくなります。

Server:Windows 7 + SqlServer 2008 R2(開発者版) クライアント:Raspberrypi 3B +、Asp.net Core + EF Core

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top