Mysqlが大きなページを使用して、ulimitを設定する必要があります。これは、limits.confで行いました。ただし、limits.conf(pam_limits.so)は、「実際の」シェルに対してのみ、initに対して読み込まれません。これを解決するには、initscript start関数に「ulimit -l」を追加しました。ボックスをchefで管理し、RPMが実際に所有しているファイルを引き継がないようにしたいので、これを行うにはある程度の繰り返し可能な方法が必要です。
$ echo "* hard nofile 102400" >> /etc/security/limits.conf
$ echo "* soft nofile 102400" >> /etc/security/limits.conf
$ sysctl -w fs.file-max=102400
$ sysctl -p
4つの手順でシステムの制限をすぐに変更でき、再起動後も引き続き機能します。数値「102400」は、必要に応じてLinuxシステムの最大オープンファイル数に変更できます。そして
$ sysctl -p
指定されたファイルからsysctl設定をロードするか、指定されていない場合は/etc/sysctl.confをロードします。
/etc/sysctl.confは、ulimits項目を設定できるはずです。これをうまくテストすることはできませんでしたが、sysctl.confに設定した後で停止できるはずです。
私はそれがまだ問題であることを示すさまざまなトピックを見つけましたが、私のチームとこれに関するいくつかのオプションについて話し合いましたが、2つの潜在的な回避策を見つけました。
オプション1:ほとんどのrhel initscriptsソース/etc/init.d/functions、そこでulimit設定を変更できます
オプション2:initは、/ etc/initscriptが毎回読み込まれる前に毎回ソースされると主張しています: http://linux.die.net/man/5/initscript 。興味深いことに、彼らは人々がulimitを設定できる場所と言っています=)
このURLに基づく自己完結型のレシピスニペット:
http://pro.benjaminste.in/post/318453669/increase-the-number-of-file-descriptors-on-centos-
レシピスニペット:
Ruby_block "edit /etc/sysctl.conf" do
_file = "/etc/sysctl.conf"
_comment = "# Tweak BY CHEF"
_content = "fs.file-max = 512000"
block do
file = Chef::Util::FileEdit.new(_file)
file.insert_line_if_no_match(/#{Regexp.escape(_comment)}/, "#{_comment}\n#{_content}")
file.write_file
end
not_if "cat #{_file} | grep '#{_comment}'"
notifies :run, "execute[sysctl -p]", :immediately
end
execute "sysctl -p" do
command "sysctl -p"
returns 255 # which would normally signify error, but doesn't on sysctl on CentOS
action :nothing
end
Ruby_block "edit /etc/security/limits.conf" do
_file = "/etc/security/limits.conf"
_comment = "# Tweak BY CHEF"
_content = "* - nofile 65535"
block do
file = Chef::Util::FileEdit.new(_file)
file.insert_line_if_no_match(/#{Regexp.escape(_comment)}/, "#{_comment}\n#{_content}")
file.write_file
end
not_if "cat #{_file} | grep '#{_comment}'"
end
(記事25304 (サブスクリプションが必要)で説明されているRedHatの方法は、適切なulimitステートメントを/etc/sysconfig/<service name>
に追加することです。例えば:
# echo "ulimit -SHn 10240 # nfile" >> /etc/sysconfig/myServiceName
(myServiceNameの代わりに、サービスの既存のファイルを使用してください。)
RedHat "sysconfig"スクリプトを使用せずに起動するデーモンの場合、適切なulimit行をデーモン起動スクリプトに追加する必要があります。
私の解決策は単に私たちのシェフのレシピでこれを行うことでした:
# Ensure ulimits are properly set for the initscript
bash "Set Ulimits" do
user "root"
code <<-EOH
echo -e "n#Setting ulimits. Performed by chef recipe MYSQLULIMIT\nulimit -l" >> /etc/sysconfig/init
EOH
not_if "grep MYSQLULIMIT /etc/sysconfig/init"
end
これにより、ulimit -l
がすべてのinitscriptに設定されます。これは、一部の環境では望ましくない場合がありますが、私の場合は問題ありません。
完璧な世界では、RPMを更新して/etc/sysconfig/mysqld
を含め、同じulimit -lコマンドをそこに入れます。
これがどれほどディストリビューション固有であるかはわかりませんが、Ubuntuで/etc/security/limits.d/20-somefile.conf
を使用してセキュリティ制限の増加を組み込んだところです。
既存のファイルを変更する代わりに、クックブックにERBテンプレートを用意し、属性ファイルにデフォルトの属性を設定して、Rubyブロックを "insert_line_if_no_match"でブロックすることを心配する必要はありません。もの-それはもう少し複雑に思え、レシピは次のようにもう少し読みやすくなります:
execute "activate_sysctl" do
user "root"
command "sysctl -p /etc/sysctl.d/10-filemax.conf"
action :nothing
end
template "/etc/sysctl.d/10-filemax.conf" do
source "system/filemax.conf"
action :create
notifies :run, "execute[activate_sysctl]", :immediately
end
そして、これは私のテンプレートファイルです:
fs.filemax = <%= node[:mycookbook][:system_fs_filemax] %>
マニュアルページによると、ulimitは非推奨です。 setrlimitを使用する必要があります。問題は、bashコマンドではなくシステムコールであることです。
私は監督者とこの問題を抱えていましたが、これは私が見つけたものです。プロセスにsetrlimit()システムコールの呼び出しを可能にする設定ファイルがない場合。 /etc/init.d bashスクリプトにulimitを設定します。これがプロセスを開始するサービススクリプトです。
スーパーバイザdのようなプロセスに構成ファイルがある場合は、その構成ファイルを使用してファイルの数を設定し、プロセスにsetrlimits()を直接呼び出させることができます。
スーパーバイザー: http://supervisord.org/configuration.html#supervisord-section-settings