トップ回答者
SQL Server 2008 SP1

質問
-
Windows Server 2008 上でSQL Server 2008を運用中に突然イベントログに「このクエリを実行するには、リソース プール 'internal' のシステム メモリが不足しています。」
が記録され、クライアントからの応答がストップしてしまいます。
SQL側のログには「エラー: 701、重大度: 17、状態: 123」と「There is insufficient system memory in resource pool 'internal' to run this query.」が記録されています。
SQLサービス(インスタンス)を再起動すると通常通りに動作するのですが、1週間ぐらいでまた同じエラーメッセージが出ます。
自分なりに調べてみてOSのページファイルサイズを「自動管理する」から物理メモリーの約2倍である「8096MB」に変更し、
SQL2008の最大サーバーメモリサイズを「3096MB」に変更してみました。
データベースのファイルサイズは「225MB」で、ログファイルのサイズは「約6GB」あります。
上記以外はデフォルト設定にしています。
自分では原因がつかめず途方にくれています。何か問題となるようなところはありますでしょうか?
よろしくお願いします。
回答
-
> はい、クライアントの接続は残ったままのようです。
どうやら「リソースリーク」っぽいですね。
以下参考サイトです。「リソースリーク」 もしくは 「コネクションリーク」 を注意して読んでみることをお勧めします。
http://blogs.msdn.com/nakama/archive/2009/01/02/net-part-2.aspx
また、コネクションリークに関するスレを見つけました。中盤あたりに話が出てきます。
http://social.msdn.microsoft.com/Forums/ja-JP/vwdexpressja/thread/1724b550-564f-47d9-8097-5739b7a2a55a
SQLServer を使っているとなると、クライアントがWindows アプリケーションか ASP.NET か判りませんが
ほぼ間違いなく ADO.NET による接続だと思われます。
ADO.NET は表示系は基本的に「非接続型 データアクセス」であり、データベース接続とSQL実行を極力短時間で行い
クライアントPCのインメモリ上にデータを展開することによって、サーバーの負荷やリソースを軽減する仕組みになっております。
また更新系は接続型ですが、これも 「接続は極力短時間に抑え、いらなくなったらすぐ切断する」 が基本です。
よって通常は、コネクションを Open した後、処理が終わったらただちに Close するのが基本なわけですが、
お行儀が悪いシステムだと、Close し忘れてる場合があったりしますが、中には最悪の場合だと、Open しっぱなしのケースもあるかも知れません。
もし当該システムのコネクションが常につなぎっぱなしであるなら、まさに最悪のケースに該当している可能性があります。
私も決して一級のエンジニアとは言えませんが、ADO.NETを使う以上は、
Open した後必要なくなったら直ちに Close するのは当たり前と、初心の時点から叩き込まれております。
いずれにせよ、サーバーの高可用性(アベイラビリティ)は重大なテーマですので、
一回システムを全般的に見直してみることをお勧めします。
また時間があったら、以下の本を読んでみるといいかも知れません。
.NETエンタープライズWebアプリケーション開発技術大全〈Vol.2〉ASP.NET基礎編
.NETエンタープライズWebアプリケーション開発技術大全〈Vol.3〉ASP.NET応用編
実はこの本、最近某所で著者ご本人から頂きまして、時間を見てはずっと目を通しているのですが、
ADO.NET の基礎知識はもちろんのこと、以下にシステムを保守・運営するか、
実践的なノウハウが凝縮されてます。名著です。 -
> クライアント側のソフトは別業者が作成しているので、簡単に変更できないのです。ほんとうにクライアント側が悪いのかどうかが気になりますが、
これは私も気になるところです。
思い出したのですが、以前やった案件で、エンドユーザーである営業さんが、マシンを起動したまま出張に行くケースもあると顧客から聞いたことがあります。
しかし、ほとんどの会社はクライアントマシンを落として帰ることが多いでしょうから、繋ぎっぱなしという状況はあるのだろうか?
また基本的には表示系は全て DataSet で取得してインメモリで確保しておくので、
DataReader でも使わない限り繋ぎっぱなしってことが本当にあるのだろうかと疑問に思えてきました。
> クライアントの接続は残ったままのようです。
とのことでしたが、これは何で調べられたのでしょうか?
Management Studio なら、オブジェクトエクスプローラの 「管理」 → 「利用状況」 → 「プロセス情報」 で接続しているユーザーは調べられるのでしょうが・・・> SQL側で再起動以外の対策があればと思います。ほんとうにコネクションが残りっぱなしなだけならコネクションをサーバー側で捨てるということも考えらると思いますがそういった方法があるかどうかについては残念ながらわかりません。
残りっぱなしのコネクションが、果たして本当にバグ(広い意味での)なのか、それとも業務内容に基づくものなのか
まずは調査が必要になるかと思います。- 回答としてマーク 高橋 春樹 2009年12月3日 5:42
-
> クライアントはVB6で作成されている条件では、サーバ側での対処は無理なのでしょうか?
VB6 だと基本はADO だと思いますが、ADO の接続がどういう仕組みになっているのか、すいませんが忘れてしまいました。orz
#というか、そもそも ADO はあまり扱ったことがない。
またコネクションをサーバー側で切断した場合、どういう現象が発生するか、問題ないような気もしますが、システムの仕様を調査しない限り何とも言えません。
ただし帰社時には必ずアプリを終了するよう通達する等、運用でカバーするとか、
そもそも深夜操作するユーザーが完全にあり得ないなら、サーバー側で対処してもいいかとは思います。- 回答としてマーク 高橋 春樹 2009年12月3日 5:43
すべての返信
-
あんにん こんにちは。
>使っているうちにリソースが不足するという状況から、>コネクションは残りっぱなしになっていないでしょうか?
はい、クライアントの接続は残ったままのようです。
夜間などのアイドル時間にクライアントの強制切断などの手段をとったほうが良いのでしょうか?
昨日、SQL Management Studioから強制的にクライアントを切断してみたのですが、リソースの解放?は
されなかったようです。
(タスクマネージャーのパフォーマンスからの確認)
結局、SQLServer(該当のインスタンス)サービスの再起動を行いました。
このとき、メモリー消費が約3.5GBから2.3GBまで低下しました。
このときのSQLSERVRプロセスが消費しているメモリー( タスクマネージャーのプロセス)は1.5GBから230MB程度まで低下しています。
クライアントが接続しっぱなしの時には、途中でサービス再起動などの対応が必要なのでしょうか?
以上、よろしくお願いします。 -
> はい、クライアントの接続は残ったままのようです。
どうやら「リソースリーク」っぽいですね。
以下参考サイトです。「リソースリーク」 もしくは 「コネクションリーク」 を注意して読んでみることをお勧めします。
http://blogs.msdn.com/nakama/archive/2009/01/02/net-part-2.aspx
また、コネクションリークに関するスレを見つけました。中盤あたりに話が出てきます。
http://social.msdn.microsoft.com/Forums/ja-JP/vwdexpressja/thread/1724b550-564f-47d9-8097-5739b7a2a55a
SQLServer を使っているとなると、クライアントがWindows アプリケーションか ASP.NET か判りませんが
ほぼ間違いなく ADO.NET による接続だと思われます。
ADO.NET は表示系は基本的に「非接続型 データアクセス」であり、データベース接続とSQL実行を極力短時間で行い
クライアントPCのインメモリ上にデータを展開することによって、サーバーの負荷やリソースを軽減する仕組みになっております。
また更新系は接続型ですが、これも 「接続は極力短時間に抑え、いらなくなったらすぐ切断する」 が基本です。
よって通常は、コネクションを Open した後、処理が終わったらただちに Close するのが基本なわけですが、
お行儀が悪いシステムだと、Close し忘れてる場合があったりしますが、中には最悪の場合だと、Open しっぱなしのケースもあるかも知れません。
もし当該システムのコネクションが常につなぎっぱなしであるなら、まさに最悪のケースに該当している可能性があります。
私も決して一級のエンジニアとは言えませんが、ADO.NETを使う以上は、
Open した後必要なくなったら直ちに Close するのは当たり前と、初心の時点から叩き込まれております。
いずれにせよ、サーバーの高可用性(アベイラビリティ)は重大なテーマですので、
一回システムを全般的に見直してみることをお勧めします。
また時間があったら、以下の本を読んでみるといいかも知れません。
.NETエンタープライズWebアプリケーション開発技術大全〈Vol.2〉ASP.NET基礎編
.NETエンタープライズWebアプリケーション開発技術大全〈Vol.3〉ASP.NET応用編
実はこの本、最近某所で著者ご本人から頂きまして、時間を見てはずっと目を通しているのですが、
ADO.NET の基礎知識はもちろんのこと、以下にシステムを保守・運営するか、
実践的なノウハウが凝縮されてます。名著です。 -
ひらぽんさん、こんにちは。
>また更新系は接続型ですが、これも 「接続は極力短時間に抑え、いらなくなったらすぐ切断する」 が基本です。
>もし当該システムのコネクションが常につなぎっぱなしであるなら、まさに最悪のケースに該当している可能性があります。
おそらく常に接続しているままと思われます。(SQL Management Studioでの観察では、クライアントのセッションが維持された状態でした)
クライアント側のソフトを改善するには大変な変更が必要となり、また別業者がクライアントソフトを裂く制定いるので、
出来ればSQL側だけで何とか対処したかったのです。
しかし。それが不可能であればソフトウエアを作成している会社に、クライアントアクセスの方法を改善していただくようにします。 -
> クライアント側のソフトは別業者が作成しているので、簡単に変更できないのです。ほんとうにクライアント側が悪いのかどうかが気になりますが、
これは私も気になるところです。
思い出したのですが、以前やった案件で、エンドユーザーである営業さんが、マシンを起動したまま出張に行くケースもあると顧客から聞いたことがあります。
しかし、ほとんどの会社はクライアントマシンを落として帰ることが多いでしょうから、繋ぎっぱなしという状況はあるのだろうか?
また基本的には表示系は全て DataSet で取得してインメモリで確保しておくので、
DataReader でも使わない限り繋ぎっぱなしってことが本当にあるのだろうかと疑問に思えてきました。
> クライアントの接続は残ったままのようです。
とのことでしたが、これは何で調べられたのでしょうか?
Management Studio なら、オブジェクトエクスプローラの 「管理」 → 「利用状況」 → 「プロセス情報」 で接続しているユーザーは調べられるのでしょうが・・・> SQL側で再起動以外の対策があればと思います。ほんとうにコネクションが残りっぱなしなだけならコネクションをサーバー側で捨てるということも考えらると思いますがそういった方法があるかどうかについては残念ながらわかりません。
残りっぱなしのコネクションが、果たして本当にバグ(広い意味での)なのか、それとも業務内容に基づくものなのか
まずは調査が必要になるかと思います。- 回答としてマーク 高橋 春樹 2009年12月3日 5:42
-
>とのことでしたが、これは何で調べられたのでしょうか?
Management Studioの「利用状況モニター」内の「プロセス」で確認しました。
>業務内容によっては、クライアントが接続している状況で、サーバー側が勝手にコネクションを切断するのはまずいと思います。
確認した時間帯は深夜で、業務が終了している時間に行いました。
したがって、通常はクライアント接続が無くなってしかるべき時間です。
クライアント側でなにかバッチを動作させていることもありませんので、ユーザーが接続を切らずに帰社しているものと思われます。
クライアントはVB6で作成されている条件では、サーバ側での対処は無理なのでしょうか? -
> クライアントはVB6で作成されている条件では、サーバ側での対処は無理なのでしょうか?
VB6 だと基本はADO だと思いますが、ADO の接続がどういう仕組みになっているのか、すいませんが忘れてしまいました。orz
#というか、そもそも ADO はあまり扱ったことがない。
またコネクションをサーバー側で切断した場合、どういう現象が発生するか、問題ないような気もしますが、システムの仕様を調査しない限り何とも言えません。
ただし帰社時には必ずアプリを終了するよう通達する等、運用でカバーするとか、
そもそも深夜操作するユーザーが完全にあり得ないなら、サーバー側で対処してもいいかとは思います。- 回答としてマーク 高橋 春樹 2009年12月3日 5:43