CentOS 6系のスレッドの上限値に注意!

アドウェイズエンジニアの波切です、こんにちは。

すでにタイトルでネタばれしちゃってますが、
最近はまったMySQLのトラブルで、WebからMySQLへの接続で、
Can't create a new thread (errno 11)
というエラーが出るという問題があったので、それについて書こうかと思います。

上記のエラーについてググってみたところ、
http://mysqlpracticewiki.com/index.php/Can%27t_create_a_new_thread_%28errno_11%29

スレッドの作成に失敗した時に発生するエラーで
メモリが足りなくなったか、もしくはスレッドの作成数の限界に達したという問題でした。
そこで、どちらが問題になったのかを切り分けるため、Cactiを見てみることにしました。

まずは、Cacti!!
cacti01












Cactiを見てみると、メモリに関してはスワップを使っている様子もなく
問題なさそう。

cacti02











MySQLへの接続数を見てみると、エラーが発生した前後でスレッド数が
跳ね上がっている様子が見られました。

そこで、疑わしいOSのスレッド数の限界値についてを調べてみることにしました。

OSの制限値の見方、Linuxのスレッド数の制限はどうなってるの?

まずは、問題となっているMySQLのプロセスにかけられている制限値を、
下記のコマンドで確認してみます。

cat /proc/`pidof mysqld`/limits

すると、
terminal














Max Processes のSoft limit値が1024に制限されているようです。
これは、怪しい!

MySQLは、コネクションごとにスレッドを作るため、
Max Processesの制限値がプロセスだけではなく、スレッド数にも影響を与えるとすると、
この制限に引っかかったのではないかと、推測されます。

そこで、下記のような何も行わないLinuxのスレッド&プロセスを作るサンプルプログラムを
作って、Max Processesの限界値付近で、どんな挙動をするのか検証を行ってみます。


すると、
terminal02















↑こんな感じになりました。
Max processes近辺で問題のerrno=11が出ちゃってますね。

また、MaxProcessは、プロセス数だけではなく、プロセス数+スレッド数の合計に対しての
制限値であるらしいと分かりました。

CentOS 6系のスレッドの上限値に注意!

ここまで調べて、CentOSのバージョン6.0からMax Processesがデフォルトで
1024に制限されていた
という事実に気づかされました。やられた…。

普段、OSの制限値を意識する機会は、あまりないため、
CentOS6系でサーバの同時接続数を多く設定している場合は、要注意です!!。

[CentOS6で制限されているプロセス最大数を制限解除する]
http://d.hatena.ne.jp/akuwano/20120413/1334312849

[ulimitが効かない不安を無くす設定]
http://blog.father.gedow.net/2012/08/08/ulimit-configuration/

対応方法


MySQLの起動ファイルの先頭に、下記の記述を加え、

ulimit -u 4096

デーモンの再起動を行うことで無事対応を終えました。
みなさんも同じ罠にハマらないようにご注意を…。

[今回のソース]
https://github.com/fugafigs/linux_thread_test