トップ回答者
SqlCommand タイムアウトエラーについて

質問
-
いつも参考にさせていただいています。
mihasato25です。よろしくお願いします。
6年前から稼働している社内システムについてですが、サーバリプレース後、
SqlCommand タイムアウトエラーが発生するようになりました。状況は以下のとおりです。
■稼働システム
ADO.NETで社内SQL Serverへリモート接続し、各種テーブル更新を行う。
Visual Studio 2008 (VB.NET) で作成。対象フレームワーク .NET Framework 2.0
■サーバリプレース (昨年10月に実施)
(旧)
ブレードサーバー
Windows Server 2008 R2、SQL Server 2008 Standard Edtion
(新)
Hyper-Vサーバ上で仮想サーバとして構築。スタンバイ機(Hyper-Vサーバ)へレプリケーションを実行。
Windows Server 2012 R2 DataCenter、SQL Server 2014 Standard Edtion
※DBの移行は、SQLSv2008バックアップファイルを用いて復元 (復旧モデル 完全)
■日次処理 (連携データを用いていテーブルの更新)
リプレース前 : 大量データ処理時にまれにタイムアウトエラー発生(年1回程度)
リプレース後 : 月に数回発生。発生個所はランダム
■タイムアウトエラーログ (3月発生ログから抜粋)
「エラー元 :.Net SqlClient Data Provider」 「エラー番号:5」 「エラー内容:System.Data.SqlClient.SqlException: タイムアウトに達しました。操作が完了する前にタイムアウト期間が過ぎたか、またはサーバーが応答していません。」 場所 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) 場所 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) 場所 System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error) 場所 System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj) 場所 System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket() 場所 System.Data.SqlClient.TdsParserStateObject.ReadBuffer() 場所 System.Data.SqlClient.TdsParserStateObject.ReadByte() 場所 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 場所 System.Data.SqlClient.SqlDataReader.ConsumeMetaData() 場所 System.Data.SqlClient.SqlDataReader.get_MetaData() 場所 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) 場所 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) 場所 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) 場所 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) 場所 System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) 場所 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) 場所 System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior) 場所 System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) 場所 System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior) 場所 System.Data.Common.DbDataAdapter.Fill(DataTable dataTable) 「エラー元 :.Net SqlClient Data Provider」 「エラー番号:5」 「エラー内容:System.Data.SqlClient.SqlException: タイムアウトに達しました。操作が完了する前にタイムアウト期間が過ぎたか、またはサーバーが応答していません。」 場所 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) 場所 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) 場所 System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error) 場所 System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj) 場所 System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket() 場所 System.Data.SqlClient.TdsParserStateObject.ReadBuffer() 場所 System.Data.SqlClient.TdsParserStateObject.ReadByte() 場所 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 場所 System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async) 場所 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) 場所 System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 「エラー元 :.Net SqlClient Data Provider」 「エラー番号:5」 「エラー内容:System.Data.SqlClient.SqlException: タイムアウトに達しました。操作が完了する前にタイムアウト期間が過ぎたか、またはサーバーが応答していません。」 場所 System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) 場所 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) 場所 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) 場所 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 場所 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) 場所 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) 場所 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) 場所 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) 場所 System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 「エラー元 :.Net SqlClient Data Provider」 「エラー番号:5」 「エラー内容:System.Data.SqlClient.SqlException: タイムアウトに達しました。操作が完了する前にタイムアウト期間が過ぎたか、またはサーバーが応答していません。」 場所 System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) 場所 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) 場所 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) 場所 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 場所 System.Data.SqlClient.SqlDataReader.ConsumeMetaData() 場所 System.Data.SqlClient.SqlDataReader.get_MetaData() 場所 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) 場所 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) 場所 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) 場所 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) 場所 System.Data.SqlClient.SqlCommand.ExecuteScalar()
上記にも記載していますが、新サーバ切替後、処理データ量に関係なくランダムに発生します。
また、実行時必ず起こるわけでもなく、発生しない月もあります。
ただ、リプレース前は大量データ (数千件) での更新以外、タイムアウトは発生しませんでした。
SQL Server のエディションをあげた影響でしょうか? Framework が古い事が原因でしょうか?
自分なりに調べて見ましたが、原因が特定できなかった為、お知恵を借りたく質問させていただきます。
よろしくお願いします。
- 編集済み mihasato25 2016年4月4日 1:52
回答
-
下記を検討される事をお奨めします。
・DBサーバーのメモリは足りているか?
→OS、SQL Serverともバージョンが変わっていますので、処理の際に使用する物理メモリの量が変わる事が考えられます。
物理メモリの量が足りないと急激に処理速度が低下します。
・クエリやインデックスにチューニングを実施する余地が無いか?
→SQL クエリアナライザ等で解析して処理が重い所を見直すだけで効果が出る事もあります。
・Hyper-Vのバックアップ方式による影響はあるか?
→VMWareでVSSとバックアップツールの組み合わせの影響で、バックアップが行われる際に全てのプロセスを凍結させられます。
SQL Serverに限らず、データ転送やバッチ処理にまで影響が出ていました。似たような事がHyper-Vでも発生していないか
調査してみてください。
SQL Serverの中の処理で行われている事であれば、.NET Frameworkのバージョンは影響すると考え辛いです。- 回答としてマーク 星 睦美 2016年5月18日 6:10
すべての返信
-
下記を検討される事をお奨めします。
・DBサーバーのメモリは足りているか?
→OS、SQL Serverともバージョンが変わっていますので、処理の際に使用する物理メモリの量が変わる事が考えられます。
物理メモリの量が足りないと急激に処理速度が低下します。
・クエリやインデックスにチューニングを実施する余地が無いか?
→SQL クエリアナライザ等で解析して処理が重い所を見直すだけで効果が出る事もあります。
・Hyper-Vのバックアップ方式による影響はあるか?
→VMWareでVSSとバックアップツールの組み合わせの影響で、バックアップが行われる際に全てのプロセスを凍結させられます。
SQL Serverに限らず、データ転送やバッチ処理にまで影響が出ていました。似たような事がHyper-Vでも発生していないか
調査してみてください。
SQL Serverの中の処理で行われている事であれば、.NET Frameworkのバージョンは影響すると考え辛いです。- 回答としてマーク 星 睦美 2016年5月18日 6:10
-
Mistral_er 様
返信、ありがとうございました。
・DBサーバーのメモリは足りているか?
旧サーバと同程度のメモリー(8GB)となっています。
プロファイラーでトレースし、メモリ使用状況を確認した結果、問題はありませんでした。
・クエリやインデックスにチューニングを実施する余地が無いか?
この点は実施の余地がありますが、いかんせん毎回違う処理&テーブルでタイムアウトエラーが
発生しているので未着手です。(実施の予定はあります。)
・Hyper-Vのバックアップ方式による影響はあるか?
この点は私も疑っています。現在、5分置きにレプリケーションを行っています。
この設定を変える事も出来ますが、DR対策の意味がなくなり躊躇しているところです。
もう少し、Hyper-VのレプリカとSqlCommandについて調査してみます。
#仮にこの点が原因であれば、MSへ強く改善を要望したいですね。
ご意見、ありがとうございました。