mysqldのファイルディスクリプタ数
新規のMySQLサーバの設定をしていて、弊社に伝わる秘伝のタレ的なマニュアルを見ていたらこんな記述があった。
/etc/security/limits.conf編集 以下を追記 「* soft nofile 8000」 「* soft nofile 8000」
コレって意味あるのかなぁとふと思ったので調べてみましたのでまとめ。
(ほとんど教えてもらった。@yoku0825++ @sh2nd++ @fujiwara++ @h141gm++)
結論から言うと、rootがmysqld_safeでmysqldを起動させる場合は意味をなさないということがわかりました。
もうこのマニュアルは捨てちゃおうと思いました。ひどい!
※本エントリは、MySQL5.5(InnoDB)、CentOS5.8環境下において検証しております。お使いの環境によってはオプション名などがそのまま当てはまらないことがありますのでご注意ください。
ファイルディスクリプタ
ファイルディスクリプタとは、OSがファイルに入出力を行うための識別子です。
linuxにおいて、ファイルディスクリプタに関する設定項目は2つ。(数字はサンプルです)
システム全体で同時に扱えるファイルディスクリプタ数の設定。変更するには以下のいずれかの方法で。
・/proc/sys/fs/file-max の値を書き換える
・/etc/sysctl.conf に 'fs.file-max = 10000' などと追記し、sysctl -p で反映
limits.conf
limits.confにはどのユーザがどれだけのファイルディスクリプタ数を同時に扱えるかということを記述します。
しかし、limits.confの記述内容は、PAM認証を経由する場合にのみ適用されます。
ttyを持たないsystemユーザの権限で動作するデーモンプロセスに適用させるためには別にいくつかの設定をする必要があります。
参考: ulimitが効かない不安を無くす設定 | 外道父の匠
mysqld起動時の挙動
my.cnfに以下のような設定をしておくと、mysqld起動時に、mysqldが扱えるファイルディスクリプタ数の上限が8192に設定されます。
[mysqld_safe]
open_files_limit = 8192
rootがmysqld_safe経由でmysqldを起動する場合、mysqld_safeがmy.cnfを読んでulimit -n
よって、冒頭で述べたとおりlimits.confへの設定は無意味なのです。
mysqldの扱うファイルディスクリプタ数
では、my.cnfにこのように記述されていたとしたら、mysqldの扱えるファイルディスクリプタ数はどのようになるでしょうか。
max_connections = 1800 table_open_cache = 256 [mysqld_safe] open_files_limit = 8192
open_files_limit = 8192 となっているので、8192になりそうですが、この場合は9000になります。
open_files_limitの最終的な値は、以下の3つのうちで1番大きな値が選択されます。※()は例のmy.cnfの値を当てはめた場合
- open_files_limit (8192)
- max_connections * 5 (9000)
- table_open_cache * 2 + max_connections + 10 (2322)
よって、9000となります。
注意点
稼働中にmax_connectionsを変更した場合
WEBサーバのスケールアウトなどで、「too many connections」エラーが出てしまった場合、メモリなどに余裕があればmax_connectionsを増やしてみるなどすることもあると思います。
前項のmy.cnfを喰って起動しているMySQLサーバでこういうオペレーションをしたとします。
max_connectionsを増やしていますが、(起動時に設定されるので当然ですが)open_files_limitの値は増えません。
コネクション数の上限をオンラインで変更する際は、スレッドバッファの他にもこういうところに注意しないと、今度は「Too many open files」が発生してしまうこともあるかも知れません。
root@db01 Mst_(none) >show global variables like "open_files_limit"; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | open_files_limit | 9000 | +------------------+-------+ 1 row in set (0.00 sec) root@db01 Mst_(none) >show global variables like "max_connections"; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_connections | 1800 | +-----------------+-------+ 1 row in set (0.00 sec) root@db01 Mst_(none) >set global max_connections = 2000; Query OK, 0 rows affected (0.00 sec) root@db01 Mst_(none) >show global variables like "max_connections"; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_connections | 2000 | +-----------------+-------+ 1 row in set (0.00 sec) root@db01 Mst_(none) >show global variables like "open_files_limit"; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | open_files_limit | 9000 | +------------------+-------+ 1 row in set (0.00 sec) root@db01 Mst_(none) >
limits.confの影響を受ける場合
mysqld_safeを経由せず、daemontoolsなどを用いて起動させる場合はこのlimits.confの影響を受ける場合もあるそうです。
open_files_limit = 8192
色々なところでopen_files_limit = 8192という設定例を見かけますが、この数値の根拠はなんなんでしょう?わかる方教えてくださいい><
これが起源では?という情報もいただきましたが根拠がよくわかりません。
ちなみに、HandlerSocketのサンプル設定ファイルでは、上限の65535を推奨していますね。