2008年11月7日金曜日

MySQL の Out of memoryで悩む



mysql で、最近たまにエラーログに以下のような Out of memory が出ていた。


サーバは、メモリーを 6G 積んでるので Out of memory ってのが


そんなに簡単にでるとは思ってなかったので困惑してしまった。


(半年前までは、1G で、増強したばっかりだったので。。。)


今回の環境


MySQL-server-5.0.51a-tritonn.1.0.9


CentOS5.2


すべてのクエリーに対して出ているわけではなく、たまに出るって感じ。


毎秒100件程度のクエリーに対して、1日で10~20件程度、時間帯も混んでる時間帯のような気がするが


それほどでもないときもたまに出ていた。




081106 12:12:05 [ERROR] /usr/sbin/mysqld: Out of memory (Needed 2091016 bytes)



いろいろ調べてみたのだが、これといってぴったりの情報もなし。


海外のコミュニティーで同様の質問している人は見つけたけど、


読み進めても、英語なもんでどういう風に話が進んだのか詳細はわからず。


http://forum.mysqlperformanceblog.com/s/mv/tree/577/


クライアント側でメモリーがたらないかもとか、mysql の本家にはあったけど


どうもそういうわけではない。。。


http://dev.mysql.com/doc/refman/5.1/ja/out-of-memory.html


MySqlユーザMLのほうで、スレッドごとにメモリを消費する、sort_buffer_size あたりを


小さくすれば解決したらしい内容があったので試してみる


(ちょっと内容は古いし、バージョンも異なるけど)


http://www.mysql.gr.jp/mysqlml/mysql/msg/14193




myisam_sort_buffer_size=64M <- 128M
sort_buffer_size=2M <- 8M



とりあえずは、エラーログはでなくなったんだけど、


これでよかったのかな。何か間違った解決をした気がしてならない。


(行き当たりばったりだな、ホンと)


スレッドで使用するメモリー量 × 同時接続スレッド数=メモリ消費量


ってのは、わかるんだけど オーバーしたら即 Out of memory ってのもなんだかなぁ。


古いメモリーを自動的に解放したりしないのかなぁ。GC的なものは期待しすぎ?


ちょっとこの辺の仕組みにうといです。勉強不足ですみません。


まぁどのクエリーのときに、Out of memory がでるのかトレースできたら


一番よかったんだけど、毎秒 100 件近く走ってるクエリーを時間もばらばらなものを特定するのは


至難の業だなぁーっと。。。ものぐさな考えで、あきらめていました。


MySQLのパラメータの設定は、1からちゃんと勉強しなおした方がよさそうだなぁ。





1 件のコメント:

mir さんのコメント...

こんにちは。"Out of memory"というのは端的にいうとmalloc(仮想メモリ空間の割当て)失敗ですので、お気づきの通りLinux 32bitのユーザプロセス空間制限(3GB)に引っかかったということですね。mysqldプロセス全体で2.5GB以下に抑えられるようにメモリチューニングをすると良いと思います。

>古いメモリーを自動的に解放したりしないのかなぁ。GC的なものは期待しすぎ?
ちなみにmysqld(sennaを含む)のメモリは固定で消費するものと動的に割り当て/解放するものがあって、動的に使用する領域についてはもちろん不要時に自動的に解放しています。それをしないといわゆる「メモリリーク」になりますので。

動的な部分は同時スレッド数や各種バッファサイズ、投入データ量などによって変化します。32bitシステムの場合はこのあたりも見込んだ上で制限に引っかからないようにしないと行けません。

64bitシステムの場合はメモリ論理空間枯渇の心配はまずありませんが、こちらも物理メモリを超えると問題になりますので同様にメモリ使用量を制御する必要があります。