none
SQL Server 2008 SP1 RRS feed

  • 質問

  • 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」あります。
    上記以外はデフォルト設定にしています。

    自分では原因がつかめず途方にくれています。何か問題となるようなところはありますでしょうか?
    よろしくお願いします。
    2009年11月9日 5:15

回答

  • > はい、クライアントの接続は残ったままのようです。

    どうやら「リソースリーク」っぽいですね。
    以下参考サイトです。「リソースリーク」 もしくは 「コネクションリーク」 を注意して読んでみることをお勧めします。

    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 の基礎知識はもちろんのこと、以下にシステムを保守・運営するか、
    実践的なノウハウが凝縮されてます。名著です。
    • 編集済み ひらぽん 2009年11月11日 15:58 一部文章の冗長な箇所を修正しました。
    • 回答としてマーク 高橋 春樹 2009年12月3日 5:41
    2009年11月11日 15:56
  • >ログファイルのサイズは「約6GB」

    というのが凄く気にかかるのですが、ログの圧縮や切り捨ては定期的に行われてますか?
    2009年11月9日 5:33
  • > SQLサービス(インスタンス)を再起動すると通常通りに動作するのですが、1週間ぐらいでまた同じエラーメッセージが出ます。

    使っているうちにリソースが不足するという状況から、
    コネクションは残りっぱなしになっていないでしょうか?
    2009年11月9日 10:50
  • 毎晩再起動で問題ないのであれば、
    それも有効な手段だと思います。

    ASP.NET などを使った webシステムでしょうか。
    だとすると詳しくないのですが、
    一般的には必要なくなった時点でコネクションを破棄し
    リソースを開放するものだと思います。
    というか、「処理」の度に接続→処理→切断するべきかもしれません。

    もしかしたら、すでにそういう仕組みになっているのに
    うまくリソースが開放されてないだけかもしれませんが、、、
    具体的な意見が出せなくて恐縮です。
    2009年11月11日 13:24
  • > クライアント側のソフトは別業者が作成しているので、簡単に変更できないのです。

    ほんとうにクライアント側が悪いのかどうかが気になりますが、

     これは私も気になるところです。

    思い出したのですが、以前やった案件で、エンドユーザーである営業さんが、マシンを起動したまま出張に行くケースもあると顧客から聞いたことがあります。
    しかし、ほとんどの会社はクライアントマシンを落として帰ることが多いでしょうから、繋ぎっぱなしという状況はあるのだろうか?
    また基本的には表示系は全て DataSet で取得してインメモリで確保しておくので、
    DataReader でも使わない限り繋ぎっぱなしってことが本当にあるのだろうかと疑問に思えてきました。

    > クライアントの接続は残ったままのようです。

    とのことでしたが、これは何で調べられたのでしょうか?
    Management Studio なら、オブジェクトエクスプローラの  「管理」 → 「利用状況」 → 「プロセス情報」 で接続しているユーザーは調べられるのでしょうが・・・

    > SQL側で再起動以外の対策があればと思います。

    ほんとうにコネクションが残りっぱなしなだけなら
    コネクションをサーバー側で捨てるということも考えらると思いますが
    そういった方法があるかどうかについては残念ながらわかりません。
    業務内容によっては、クライアントが接続している状況で、サーバー側が勝手にコネクションを切断するのはまずいと思います。
    残りっぱなしのコネクションが、果たして本当にバグ(広い意味での)なのか、それとも業務内容に基づくものなのか
    まずは調査が必要になるかと思います。

    2009年11月14日 15:29
  • > クライアントはVB6で作成されている条件では、サーバ側での対処は無理なのでしょうか?

    VB6 だと基本はADO だと思いますが、ADO の接続がどういう仕組みになっているのか、すいませんが忘れてしまいました。orz

    #というか、そもそも ADO はあまり扱ったことがない。

    またコネクションをサーバー側で切断した場合、どういう現象が発生するか、問題ないような気もしますが、システムの仕様を調査しない限り何とも言えません。

    ただし帰社時には必ずアプリを終了するよう通達する等、運用でカバーするとか、
    そもそも深夜操作するユーザーが完全にあり得ないなら、サーバー側で対処してもいいかとは思います。

    2009年11月18日 2:23

すべての返信

  • >ログファイルのサイズは「約6GB」

    というのが凄く気にかかるのですが、ログの圧縮や切り捨ては定期的に行われてますか?
    2009年11月9日 5:33
  • >ログファイルのサイズは「約6GB」

    というのが凄く気にかかるのですが、ログの圧縮や切り捨ては定期的に行われてますか?
    ひらぽんさん、こんにちは
    ログの圧縮や切捨ては特に行っていません。
    現在ハードディスクドライブの空き容量に余裕があるので、まだ大丈夫ではないかと考えているのですが?

    2009年11月9日 9:33
  • 追加の情報です。

    このデータベースは以前 Windows Server 2003 + SQL Server 2000上で使用しており、
    今回 Windows Server 2008 SP1 + SQL Server 2008 SP1に乗せ変えました。
    運用はC/Sで運用しており、クライアント側はVB6を使用しています。

    このあたりも原因の一つとなりうるのでしょうか?
    2009年11月9日 10:10
  • > SQLサービス(インスタンス)を再起動すると通常通りに動作するのですが、1週間ぐらいでまた同じエラーメッセージが出ます。

    コネクション残りっぱなしとかは大丈夫でしょうか?
    2009年11月9日 10:41
  • > SQLサービス(インスタンス)を再起動すると通常通りに動作するのですが、1週間ぐらいでまた同じエラーメッセージが出ます。

    使っているうちにリソースが不足するという状況から、
    コネクションは残りっぱなしになっていないでしょうか?
    2009年11月9日 10:50
  • あんにん こんにちは。
    使っているうちにリソースが不足するという状況から、
    >コネクションは残りっぱなしになっていないでしょうか?

    はい、クライアントの接続は残ったままのようです。
    夜間などのアイドル時間にクライアントの強制切断などの手段をとったほうが良いのでしょうか?

    昨日、SQL Management Studioから強制的にクライアントを切断してみたのですが、リソースの解放?は
    されなかったようです。
    (タスクマネージャーのパフォーマンスからの確認)

    結局、SQLServer(該当のインスタンス)サービスの再起動を行いました。
    このとき、メモリー消費が約3.5GBから2.3GBまで低下しました。
    このときのSQLSERVRプロセスが消費しているメモリー(
    タスクマネージャーのプロセス)は1.5GBから230MB程度まで低下しています。
    クライアントが接続しっぱなしの時には、途中でサービス再起動などの対応が必要なのでしょうか?

    以上、よろしくお願いします。
    2009年11月11日 11:19
  • 毎晩再起動で問題ないのであれば、
    それも有効な手段だと思います。

    ASP.NET などを使った webシステムでしょうか。
    だとすると詳しくないのですが、
    一般的には必要なくなった時点でコネクションを破棄し
    リソースを開放するものだと思います。
    というか、「処理」の度に接続→処理→切断するべきかもしれません。

    もしかしたら、すでにそういう仕組みになっているのに
    うまくリソースが開放されてないだけかもしれませんが、、、
    具体的な意見が出せなくて恐縮です。
    2009年11月11日 13:24
  • > はい、クライアントの接続は残ったままのようです。

    どうやら「リソースリーク」っぽいですね。
    以下参考サイトです。「リソースリーク」 もしくは 「コネクションリーク」 を注意して読んでみることをお勧めします。

    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 の基礎知識はもちろんのこと、以下にシステムを保守・運営するか、
    実践的なノウハウが凝縮されてます。名著です。
    • 編集済み ひらぽん 2009年11月11日 15:58 一部文章の冗長な箇所を修正しました。
    • 回答としてマーク 高橋 春樹 2009年12月3日 5:41
    2009年11月11日 15:56
  • あんにんごさん、こんにちは。

    >毎晩再起動で問題ないのであれば、
    >それも有効な手段だと思います。
    有り難うございます、定期的なサービスの再起動を検討してみます。

    クライアント側のプログラムは別の業者が作成し手織り、変更するには大変な料力が必要となる為、出来る限りSQLサーバー側での
    対応をしたかったのです。

    >「処理」の度に接続→処理→切断するべきかもしれません。
    クライアント側のソフトは別業者が作成しているので、簡単に変更できないのです。
    SQL側で再起動以外の対策があればと思います。

    2009年11月13日 11:10
  • ひらぽんさん、こんにちは。

    >また更新系は接続型ですが、これも 「接続は極力短時間に抑え、いらなくなったらすぐ切断する」 が基本です。

    >もし当該システムのコネクションが常につなぎっぱなしであるなら、まさに最悪のケースに該当している可能性があります。
    おそらく常に接続しているままと思われます。(SQL Management Studioでの観察では、クライアントのセッションが維持された状態でした)
    クライアント側のソフトを改善するには大変な変更が必要となり、また別業者がクライアントソフトを裂く制定いるので、
    出来ればSQL側だけで何とか対処したかったのです。
    しかし。それが不可能であればソフトウエアを作成している会社に、クライアントアクセスの方法を改善していただくようにします。
    2009年11月13日 11:16
  • > クライアント側のソフトは別業者が作成しているので、簡単に変更できないのです。

    ほんとうにクライアント側が悪いのかどうかが気になりますが、
    そういった事情ならしかたないですね。

    > SQL側で再起動以外の対策があればと思います。

    ほんとうにコネクションが残りっぱなしなだけなら
    コネクションをサーバー側で捨てるということも考えらると思いますが
    そういった方法があるかどうかについては残念ながらわかりません。
    2009年11月14日 0:39
  • > クライアント側のソフトは別業者が作成しているので、簡単に変更できないのです。

    ほんとうにクライアント側が悪いのかどうかが気になりますが、

     これは私も気になるところです。

    思い出したのですが、以前やった案件で、エンドユーザーである営業さんが、マシンを起動したまま出張に行くケースもあると顧客から聞いたことがあります。
    しかし、ほとんどの会社はクライアントマシンを落として帰ることが多いでしょうから、繋ぎっぱなしという状況はあるのだろうか?
    また基本的には表示系は全て DataSet で取得してインメモリで確保しておくので、
    DataReader でも使わない限り繋ぎっぱなしってことが本当にあるのだろうかと疑問に思えてきました。

    > クライアントの接続は残ったままのようです。

    とのことでしたが、これは何で調べられたのでしょうか?
    Management Studio なら、オブジェクトエクスプローラの  「管理」 → 「利用状況」 → 「プロセス情報」 で接続しているユーザーは調べられるのでしょうが・・・

    > SQL側で再起動以外の対策があればと思います。

    ほんとうにコネクションが残りっぱなしなだけなら
    コネクションをサーバー側で捨てるということも考えらると思いますが
    そういった方法があるかどうかについては残念ながらわかりません。
    業務内容によっては、クライアントが接続している状況で、サーバー側が勝手にコネクションを切断するのはまずいと思います。
    残りっぱなしのコネクションが、果たして本当にバグ(広い意味での)なのか、それとも業務内容に基づくものなのか
    まずは調査が必要になるかと思います。

    2009年11月14日 15:29
  • >とのことでしたが、これは何で調べられたのでしょうか?
    Management Studioの「利用状況モニター」内の「プロセス」で確認しました。

    >業務内容によっては、クライアントが接続している状況で、サーバー側が勝手にコネクションを切断するのはまずいと思います。
    確認した時間帯は深夜で、業務が終了している時間に行いました。
    したがって、通常はクライアント接続が無くなってしかるべき時間です。
    クライアント側でなにかバッチを動作させていることもありませんので、ユーザーが接続を切らずに帰社しているものと思われます。

    クライアントはVB6で作成されている条件では、サーバ側での対処は無理なのでしょうか?
    2009年11月16日 7:23
  • > クライアントはVB6で作成されている条件では、サーバ側での対処は無理なのでしょうか?

    VB6 だと基本はADO だと思いますが、ADO の接続がどういう仕組みになっているのか、すいませんが忘れてしまいました。orz

    #というか、そもそも ADO はあまり扱ったことがない。

    またコネクションをサーバー側で切断した場合、どういう現象が発生するか、問題ないような気もしますが、システムの仕様を調査しない限り何とも言えません。

    ただし帰社時には必ずアプリを終了するよう通達する等、運用でカバーするとか、
    そもそも深夜操作するユーザーが完全にあり得ないなら、サーバー側で対処してもいいかとは思います。

    2009年11月18日 2:23
  • >深夜操作するユーザーが完全にあり得ないなら、サーバー側で対処してもいいかとは思います。

    皆様有り難うございました。
    クライアント側での対処には時間がかかりそうなので、SQLサービスの再起動にて回避することにしました。

    今後皆様にいただいたコメントを参考にして、クライアント側のソフト改修をお願いすることにします。
    2009年11月26日 4:36
  • こんにちは。フォーラムオペレーターの高橋春樹です。

    ひらぽんさん、あんにんごさん、いつもお世話になっております。

    S.Takedaさん、初めまして。
    MSDNフォーラムのご利用ありがとうございます。

    問題の回避策と今後の対応方法が決まって良かったです。
    今回、ひらぽんさんとあんにんごさんからのアドバイスが有用な情報だと思いましたので、
    勝手ながら、皆様からの投稿に、回答マークを付けさせてもらいました。

    今後ともMSDNフォーラムを宜しくおねがいします(^_^)


    マイクロソフト株式会社 フォーラム オペレーター 高橋春樹
    2009年12月3日 5:50