

MySQLの問題解決に皆さまのお知恵をお借りしたく、ここに質問させて頂きます。

現在の症状を先に記し、自分なりに行った対処方法をその後に記しておきます。  
そして、最後にその問題に対する解決方法をご教授していただけたら幸いです。

[現状]  
現在、MySQL(5.6.29)を使って、DB内から必要なデータの取得を目指しております。  
ここでのやり取りは、「select * from table where
xxx」程度の簡単なコードを使用しています。(実際には、7百万行あるtableから、whereの条件にマッチしたcolumn(int)だけを読み込んでいます。)自作したGOプログラムから、このコードを使って、DBにアクセスし、正確なデータが取得できることは確認しております。

しかし、このGOプログアム内では、数百回ほどwhere条件を変えながら、そのたびに別のデータを取得する必要があります。何度もDBにアクセスしていますと、最終的には、Error
1040(Too many connections)が出てきてしまい、計算途中でGOプログラムが強制終了されてしまいます。

[自分で行った対処方法]  
そこで、webで自分なりに調べましたら、my.cnfファイルの条件を変更するとこの問題が解決されるとのアドバイスがありましたので、以下の2点をmy.cnfに挿入しました。  
(a) max_connections = 200  
(b) wait_timeout = 100

上記の数字(200,
100)の変更はしております。（と言いましても、1000ぐらいまでの数字でしか試しておりません。）また、関係ないとは思いますが、念の為「flush
query cache;」もコードには組み込んでいます。しかし、現状では、同じ問題が発生しております。

[質問]  
webでは探しましたが、上記の２点以外での同問題の解決方法が見つかりませんでした。  
質問は２点あります。  
（１）自分でも行いましたが、数字の変更(200,100)を上限なく大きな数字(例えば、200000など)にした場合、問題は解決されるのでしょうか？その場合、別の問題は発生しますでしょうか？  
（２）上記の２条件以外での解決方法がありますでしょうか？

大変申し訳ないですが、ご教授をいただけたら幸いです。  
よろしくお願いします。


CC BY-SA 3.0
2016-08-01T18:07:10.250
28006
2016-08-05T02:32:50.550
11048
question
mysql
MySQLでのError 1040に対する質問


問題が完全に解決したか分かりませんが、  
上記で示した問題が発生したときに使っていたデータ数（量）の１００倍のデータを計算させても、問題が発生していないことを考えると、今のところ下記で示す方法で問題が回避できると考えています。参考程度にここに書き残しておきます。

結論から言いますと、my.cnfの条件を以下のようにしました。  
(a) max_connections = 500  
(b) wait_timeout = 3600

(セーブしたあと、service mysql restartで条件を反映してください。Linux(Debian)のケースですけど。）

上記の条件に設定した理由は、ウェブなどでさらに調べた結果、同じ問題を抱えていた人が、  
max_connectionsは、200 ~ 500に設定し、  
wait_timeoutは、10 ~ 3600に設定しているのが多かったからです。

max_connectionsに関しては、「数字が大きいほどよい」と言うグループと、「それでは問題が発生する」という２グループが存在しています。wait_timeoutも同様な感じでした。

設定の仕方などで分からない方がいましたら、以下のサイトを参照することをお勧めします。非常に丁寧に書かれています。<http://koexuka.blogspot.com/2010/03/blog-
post.html>

お騒がせしました。これからもよろしくお願いします。


CC BY-SA 3.0
2016-08-04T15:38:29.890
28070
2016-08-04T15:38:29.890
11048
28006
answer


クライアントプログラムからMySQLを利用する際、

  1. MySQLサーバーに接続する
  2. その接続を利用して必要なだけクエリを投げる
  3. 接続を閉じる

という流れになります。ここで `Too many connections` とは同時に開いている接続が `max_connections`
で設定された数を超えているというエラーです。この時、

  * 実際にそれだけ同時に接続しなければならない（Webサービスなど）  
→ `max_connections` を **増やして** 、多くのコネクションを許容する

  * 何らかの問題で使われていない接続が残ってしまっている  
→ `wait_timeout` を **短くして** 、さっさとサーバー側から切断してしまう

といった対応がとられます。ですから前述のエラーに対して `wait_timeout`
を調節するとしたら短くすることになりますが、本来はクライアントが責任をもって適切なタイミングで切断するもので、タイムアウトは問題時のための予防線です。このエラーが恒常的に発生するなら、まずはその原因を調査し、使い方が間違っていないか、他の対処法がないか検討すべきです。

`max_connections`
についても、多くの接続を維持するにはそれだけのリソースが必要になりますから、環境によってその上限は様々です。また、必要十分な数に抑えておくことで、前述のエラーで異常に気づきやすくなります。この値がよく紹介されているから、ではなく、動作させる環境やアプリケーションの要件に合わせて調整すべきです。

* * *

今回の場合、ひとつのプログラムの実行中にこのエラーが起きているようですから、使いまわしも切断もせず、新しい接続を多数作成している、いわゆるリソースリークが起きているのではと思います。もちろん
`max_connections` を増やすことで済ますのも手ではありますが...。

もしそのあたりについて改めて質問されるのでしたら、問題のクエリを発行している部分のソースコードを添えて、[go](/questions/tagged/go
"'go' のタグが付いた質問を表示") タグを付けて質問するとよろしいかと思います。


CC BY-SA 3.0
2016-08-05T02:24:43.360
28076
2016-08-05T02:32:50.550
2016-08-05T02:32:50.550
8000
8000
28006
answer