- - PR -
ワーカープロセスの再起動
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2002-10-09 14:13
始めまして。
最近頻繁にワーカープロセスが落ち アプリケーションログに下記の内容が書き出されます。 『デッドロック状態である可能性があるためspnet_wp.exe (PID: xxx) が繰り返されました。この 180 秒間に保留中の要求に対して応答は何も 送信されていません。』 行っている処理は ボタン投下→@テーブルAからSELECT→AテーブルBにINSERT→終了 ※テーブルAとテーブルBは異なるデータベースに格納 ※scriptTimeoutは2時間に設定 @---SELECTした結果4000000行 SqlDataReaderで1行づつ読み込んでいます。 A---読み込んだ行をテーブルBにExecuteNonQueryにてINSERT @がEOFまでAをWhile処理内にて実行しています。 ですので、Bは4000000回実行している事になります。 ボタン投下後、何分かたつと上記に書いたように ワーカープロセスが終了してしまいます。 いろいろ調べた結果マイクロソフト サポート技術情報-JP321792を 参考にしましたが全然直らず machine.configの『responseDeadlockInterval』を 延長する事で回避ができました。 そこまではいいのですが 今僕が分からないでいるのが アプリケーションログに書き出された『デッドロック状態』です。 今まで『デッドロック状態』はデータベース内でのみ発生すると 思っていました。 が、テストで作成したアプリなので不特定多数がアクセスしておらず 処理的にデッドロックを起こす問題も見当たりません。 この症状が起こる原因がわからないと プログラムを作成する際に注意ができません。 どなたか ・この症状が起こる原因について ・『responseDeadlockInterval』の延長でもたらす他の影響 ご教授いただけないでしょうか? 何卒よろしくお願いいたします。 ----環境------ OS:Windows2000Server SP3 DB:SQLServer2000 SP3 MDAC:2.7 RTM (2.70.7713.4) .NET FrameWork:1.0.3705.288 _________________ | ||||
|
投稿日時: 2002-10-10 13:15
こんにちは。
丸数字は機種依存文字なので、使わないようにしてくださいね。 『デッドロック』についてですが、『デッドロック』というのは複数の処理があり、それらが互いが発生させるイベントを待っている状態で発生します。データベース内で起こるのではなく、データベース管理システムが行っている処理がデッドロックするのです。したがって、データベース以外でも起こります。googleで『デッドロック』を検索するといろいろ出てきますので、サマリーだけでも読んでみてください。 それで、ここで起こっているデッドロックですが、aspnet_wp.exeと、それが呼び出しているプロセスとの間で起こっています。ユーザがボタンをクリックし、aspnet_wp.exeがデータを移し替えるプロセスを呼び出して、そのプロセスが終了するというイベントを待っています。ところが、4百万の行を写す処理に時間がかかりすぎ、「規定時間内にプロセスが終了しない→デッドロック発生」となっています。 今のままだと、ユーザは処理が終了するまで画面の前で待っていなければならず、その間その他の処理もできませんよね?それよりもバックグラウンドで処理を行わせ、画面やユーザを解放できるように修正できないか、考えてみられてはどうでしょうか。 | ||||
|
投稿日時: 2002-10-10 14:37
実際はデッドロックになってなどいないが、待ち状態が長過ぎるため 「デッドロック状態にあると判断された」のだと思います。 「responseDeadlockInterval」を延長して「判断基準」を 後ろに延ばすだけで解決しているようですので。 他の影響としては「本当のデッドロックが発生した際に検出(判断)までに 時間がかかる」以外には特に無さそうに思います。 [ メッセージ編集済み 編集者: 永井和彦 編集日時 2002-10-10 14:39 ] | ||||
|
投稿日時: 2002-10-10 14:55
なんとなく誤解を与えそうなので補足。
> それで、ここで起こっているデッドロックですが、aspnet_wp.exeと、 > それが呼び出しているプロセスとの間で起こっています。ユーザがボタンを > クリックし、aspnet_wp.exeがデータを移し替えるプロセスを呼び出して、 > そのプロセスが終了するというイベントを待っています。ところが、 > 4百万の行を写す処理に時間がかかりすぎ、「規定時間内にプロセスが > 終了しない→デッドロック発生」となっています。 ここで起きている現象は厳密にはデッドロックではありません。 それこそ適当に検索していただいたらわかることですが。 他のプロセスの影響などがないと仮定すれば、単なるタイムアウトです。 responseDeadlockIntervalというパラメータは 「設定した時間内に応答がなかった場合はデッドロックが起きているとみなす」 というものなので、実際にデッドロックが起きているかは 別の点から判断をする必要があります。 で、元の質問のうち、 >・『responseDeadlockInterval』の延長でもたらす他の影響 こちらについては、 「本当のデッドロックが起きた場合にはその発見が遅れることになる」 ことが想像できます。 | ||||
|
投稿日時: 2002-10-10 15:08
ご教授大変ありがとうございました。
>丸数字は機種依存文字なので、使わないようにしてくださいね すいませんでした。以後気をつけます。 デッドロックについて勉強不足でした。 もう少し勉強してみます。 .NETだから、何でも出来るだろうという考えが甘かったです。 大量のデータ、不特定多数のユーザーを扱うアプリの時は もっと今まで以上に設計を考えないといけない見たいですね。 ASPの時は強引にScriptTimeOutでしのいでました。 しかも、メモリーもかなり使用しそうですね。 ※4000000行をDataSetに移そうとしたら メモリーリークで落ちちゃいました。 256Mのマシンだから仕方ないのかも知れませんが。 『responseDeadlockInterval』の延長で 影響があるのは検出時間がかかるだけ見たいなので 設定を延ばして様子を見ておきます。 実際のデッドロックとタイムアウトを判断するのは パフォーマンスモニタで見る方法はないのでしょうか? 今から、上司と相談しなくちゃ。 ありがとうございました。 _________________ [ メッセージ編集済み 編集者: RockSteady 編集日時 2002-10-10 15:13 ] | ||||
|
投稿日時: 2002-10-13 08:58
米田です。
>ボタン投下→@テーブルAからSELECT→AテーブルBにINSERT→終了 MS SQL Server では、1,2 と分けている点が問題を大きくしているように見えます。 INSERT SELECT を用いて、DB Server 内に処理を封じ込めたほうがいいと思います。 例 INSERT author_id SELECT au_id FROM dbname.dbo.authors 別データベースでも、省略せずに DBNAME.OWNERNAME.TABLENAME とかけば、1文で可能です。 4000000回実行(4M レコード?)となると、これだけでは、数秒に抑えることはできないかもしれませんが、性能面ではかなり違いが出ます。 | ||||
|
投稿日時: 2002-10-17 15:36
よねださんアドバイスありがとうございます。
> 別データベースでも、省略せずに DBNAME.OWNERNAME.TABLENAME 確かに、1回のINSERTを実行したほうが パフォーマンスは格段に上がりますよね。 同じSQLServer内で使用する事が前提になら 良かったんですけど、、、 のちのちには SELECTしてくる先はSQLServerとは限らなく オラクル、アクセス等ADO.NETが対応している所 全てがSELECTしてくる候補になると ボソっと耳元で上の者に言われました。 となると やっぱりWEBサービスとかに方向を変えないと ダメなんですかね。 | ||||
|
投稿日時: 2002-10-17 17:46
WebServiceのほうが処理時間はかかりそうだということは
ちゃんと抑えておかないと危険ですよ・・・ この手のものは、データベースサーバとアプリケーションサーバが 別の場所にあることによるネットワークを通じたやり取りの回数が 意外なほどボトルネックになります。 よねださんの言う > INSERT SELECT を用いて、DB Server 内に処理を封じ込めたほうがいいと思います。 というのはまさにここを逃がすための手段です。 大量のデータを流すのならば、 ファイル出力などしてデータをブロック化し、転送時に圧縮をかけるなどの 工夫をしないといけなくなりかねません。 WebServiceは魅力的に聞こえますが、レコードをブロックで扱う手段を提供しないと あとから泣きを見ることになりそうです。 |