web-dev-qa-db-ja.com

SqlExceptionのトラブルシューティングに役立つ:非負荷状態で、接続でタイムアウトが期限切れになった

トラフィックがほとんどない私のウェブサイトをホストしているサーバーがあります。
毎日数人(<20)がサイトにアクセスし、数人のRSSリーダーが私たちが提供するいくつかのフィードを購読しています。

ほぼ毎晩、RSSリーダーが真夜中に当たって、接続のタイムアウトのためにWebサイトがSQL Serverに接続できないという例外を受け取ります。詳細は非常に奇妙なので、どこから探し始めればよいかわからないので、問題の原因についてのヘルプを探しています。

Windows Server 2008ではASP.Net MVC、Entity Framework、およびSQL Server 2008を使用しています。このマシンは、厳密にはトップ層のプロバイダーから入手した専用のボックスではないため、構成が最適ではないか、誰が何を知っているかがわかりますそうしないと。
ボックスもかなり小さく、RAMは1Gbしかありませんが、今のところ、ある程度の負荷がかかるはずです...

以下の完全なコールスタックをコピーしていますが、最初に、私たちが知っていることのいくつかを示します。

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

UPDATE:提案されているようにプロファイラーをアタッチしましたが、新しい例外が発生するまでにかなり時間がかかりました。これは私たちが知っている新しいものです:

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

要するに、私はこれについて完全に無知です。何百ものクエリが連続して実行される理由を見つけることはできませんが、それらは問題と関係があるに違いないと思います。
接続の問題を診断する方法もわかりません...
または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)

どんなアイデアも非常に高く評価されます。

31
Daniel Magliola

メモリが足りません

これはメモリ問題である可能性が高く、おそらく他の事柄によって悪化または引き起こされますが、それでも本質的にメモリ問題です。他にも(可能性は低いですが)2つの可能性があります。最初に確認して削除する必要があります(簡単に実行できるため)。

可能性をチェックするのは簡単:

  1. 「自動クローズ」が有効になっている可能性があります。自動クローズはこの動作とまったく同じですが、オンにされることはまれです。これを確認するには、SSMSでアプリケーションデータベースを右クリックし、[プロパティ]を選択して、[オプション]ペインを選択します。 「自動クローズ」エントリを見て、Falseに設定されていることを確認します。 tempdbも確認してください。

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

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

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

  • 1 GBのメモリがあります。これは技術的にはSQL Serverの最小値を上回っていますが、SQL Serverの推奨値を下回っており、負荷が軽いサーバーでも、私の経験では本番環境で許容できる値を下回っています。

  • IISとSQL Serverを同じボックスで実行しています。これは、メモリの競合が発生するため、主に推奨されませんが、メモリが1 GBしかないため、 IIS、アプリ、SQL Server、OS、およびその他のタスクやメンテナンスはすべて、ごくわずかなメモリを争っています。Windowsがこれを管理する方法は、アクティブでないプロセスから積極的にメモリを奪って、アクティブなプロセスにメモリを提供することです。 SQL Serverのような大規模なプロセスが、この状況で要求を完全に処理できるように十分なメモリを取り戻すには、数秒から数分かかる場合があります。

  • プロファイラーは問題の90%を解消しました。これは、メモリが問題である可能性が高いという大きな手がかりです。通常、プロファイラーのようなものがこの特定の問題に正確にこの影響を与えるためです。プロファイラータスクはSQL Serverを単にlittleビットは常にアクティブです。多くの場合、これはOSの「スカベンジャー」リストから除外するか、少なくとも影響をいくらか軽減するのに十分なアクティビティです。

原因としてメモリを確認する方法:

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

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

  3. Perfmonで「カウンターログ」を作成して、収集したデータをファイルに送信します。これに慣れていない場合は、データをタブまたはカンマ区切りのファイルに収集して、Excelで開いて分析できるようにするのがおそらく最も簡単です。

  4. Perfmonをセットアップしてファイルに収集し、それに次のカウンターを追加します。

    -Processor \%Processor Time [合計]

    -PhysicalDisk \%Idle Time [for each disk]

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

    -メモリ\ページ/秒

    -メモリ\ページ読み取り/秒

    -Memory\Available MBytes

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

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

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

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

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

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

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

ソリューション:

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

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

ここでの問題は、それが周辺機器であるか、主な問題の原因である可能性が高いことです。プロファイラーによってインシデントの90%が解消されたので、残っているものは別の問題である可能性があります、またはそれが最も極端なものである可能性があります問題の悪化者。その動作のため、キャッシュを循環させているか、アプリケーションサーバープロセスのバックグラウンドメンテナンスが他にあると思います。

50
RBarryYoung

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

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

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

EDIT:アップデートに対処します。

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

それ以外に、ハイゼンバグを持っているようです。あなたが追加するために私が考えることができる唯一のものは、(ファイルまたはイベントログへの)もっと多くのロギングです。

1
Austin Salonen

同時に走るクローンの匂いがします。 RBarryYoungが言うように..毎晩のバックアップか、それが何か別の可能性がありますサーバーへのrootアクセス権がありますか? crontabが見えますか?

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

0
user154860

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

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

0
menxin