<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://jackxiang.com/post//</link>
<title><![CDATA[mysql非root启动解除文件句柄的1024限制的注意事项]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Wed, 25 Aug 2010 02:17:29 +0000</pubDate> 
<guid>http://jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	mysql非root启动解除文件句柄的1024限制的注意事项<br/><br/>问题描述：couldn&#039;t increase number of open files to more than 1024<br/>/usr/sbin/mysqld: Can&#039;t open file: &#039;./xxxx/xxxx.frm&#039; (errno: 24)<br/><br/>如果非root启动时不修改最大句柄数，启动日志就会出现： <br/>: Can&#039;t open file: &#039;.&#92;database&#92;certain_table.frm&#039; (errno: 24)<br/>查询原因：<br/>[~]# perror 24<br/>OS error code&nbsp;&nbsp;24:&nbsp;&nbsp;Too many open files<br/>待到句柄数耗光时，就会出现：<br/>导致mysql无法应答新连接。<br/>规避方法：<br/>在root下修改ulimit后(比如ulimit -HSn 16666 )，<br/>不能&quot;su -&quot; 或者&quot;exit&quot;到普通用户, 需要用su 到普通用户，否则修改的ulimit无效，导致句柄还是会不够用。<br/>关于修改可打开最大文件句柄数，针对不同的linux系统有不同的方案<br/><br/><br/><br/>由於最近在 mysql 上面安裝了一些系統，導致 DB 裡的 table 量大增，突然有一天 mysql 自己就掛點了，看了 log 後發現訊息如下：<br/>[ERROR] /usr/sbin/mysqld: Can&#039;t open file: &#039;./xxxx/xxxx.frm&#039; (errno: 24)<br/>.............................................<br/>[ERROR] /usr/sbin/mysqld: Can&#039;t open file: &#039;./xxxx/xxxx.frm&#039; (errno: 24)<br/>[ERROR] Error in accept: Too many open files<br/>[ERROR] Error in accept: Too many open files <br/><br/>網路上的討論有很多，包括調整系統本身的 fs.file-max 大小，還有在 /etc/my.cnf 中加入 open_files_limit 的設定值，但是實際上，光是這樣的調整是不夠或方向是不對的，因為 mysql 要開多少的 files，真正相關的不只這些設定。<br/><br/><br/>相關的設定有：<br/><br/><br/>/proc/sys/fs/file-max<br/>這是系統資源配置的最高檔案數，設定值與記憶體大小有關，早期 ram 很貴的時代，這個值通常不會太大，所以 mysql 開的檔案數如果太多，確實可能被這個值限制住，但是現在動輒數 G 的 memory，這個值在我的 linux 系統上都內定開到 20 萬以上，因此問題不在這個值。 (若真想修改這個值，可以用 sysctl -w fs.file-max=##### 來修改，但系統重開後自動改回，可寫入 /etc/rc.local 開機執行)<br/><br/><br/>ulimit -n<br/>ulimit 可以查看每個 shell 的使用資源大小，-n 參數在 man page 中是寫 The maximum number of open file descriptors，換句話說，mysql 所處的 shell，真的能開的檔案只是 ulimit -n 的值，在我的系統上 ulimit -n 的值僅有 1024，所以就算 fs.file-max 有幾十萬，mysql shell 可以開的就是 1024 而已，這才是關鍵所在。<br/><br/><br/>my.cnf 中的 table_cache, max_connections, open_files_limit 三個參數<br/>table_cache: mysql 5.1.3 版後已更名為 table_open_cache，指 mysql 開啟 table 的 cache file 數，一般 mysql 開一個 table 就會開啟 *.MYI 和 *.MYD 兩個檔，比方說我們用 phpMyAdmin 開一個有 100 個 tables 的 DB，mysql 會 cache 住 200 個 files。 (default: 64)<br/>max_connections: 最高連線數。 (default: 100)<br/>open_files_limit: mysqld 開啟的最高檔案數。 (default: 0)<br/><br/><br/>理論上 mysqld 在 open file 後會 cache 住，那它要開到多少個檔案之後，才會去釋放掉 cache 的檔案？那就得看 my.cnf 裡面，table_cache, max_connections, open_files_limit 的值，如果 open_files_limits 的值為 0，就看 table_cache 和 max_connections 透過某個函數計算出來的值；如果 open_files_limits 的值不為 0，那應該是要看這個值的大小設定。<br/><br/><br/>問題來了，那個函式怎麼算的，一般說法是 table_cache * 2 + max_connections，我自己的系統則是還要再 +10，我在 my.cnf 原本的設定是 table_cache 1024, max_connections 150, open_files_limits 則不設 (default: 0)，結果計算出來是 1024 x 2 + 150 + 10 = 2208，所以照理論來說 mysql 可以開到 2208 個檔案。但實際卻在我 DB table 數大增後，便很容易因為文章一開頭的 error 讓 mysql 掛點了。<br/><br/><br/>仔細一看 log 後更可以進一步發現這個 [Warning] Could not increase number of max_open_files to more than 1024 (request: 2208)。<br/><br/><br/>換句話說，如果 table_cache * 2 + max_connections 超過 1024 就會有警告，而 1024 便是 ulimit -n 那個 1024，即 shell 的限定使用資源。因此 mysql 真正會掛的主因是，它認為可以開到 2208 個檔，但系統只給它開到 1024 個檔，所以 mysql 就會一直去開第 1025 個檔而失敗，最後 mysql 就掛了.......<br/><br/><br/>結論就是，不管我們要將我們的 mysql 設置 open_files_limit 或是使用 table_cache * 2 + max_connections，都應該要注意 ulimit -n 的值才是正解，跟 fs.file-max 關連反而較小了。<br/><br/><br/>PS: 要查看 mysql 開啟的 files 數，可先用 ps aux &#124; grep mysql 看 mysql PID，再利用 lsof -p PID# &#124; wc -l 來統計。<br/><br/><br/><br/><br/><br/><br/><br/>/etc/security/limits.conf<br/>#&lt;domain&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;type&gt;&nbsp;&nbsp;&lt;item&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;<br/>#<br/>#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; soft&nbsp;&nbsp;&nbsp;&nbsp;core&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;禁止创建core文件<br/>#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hard&nbsp;&nbsp;&nbsp;&nbsp;rss&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10000&nbsp;&nbsp;&nbsp;&nbsp; 非root用户最多使用10M内存<br/>#@student&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hard&nbsp;&nbsp;&nbsp;&nbsp;nproc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;20&nbsp;&nbsp;&nbsp;&nbsp; 最多进程数限制在20<br/>#@faculty&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;soft&nbsp;&nbsp;&nbsp;&nbsp;nproc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 20<br/>#@faculty&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hard&nbsp;&nbsp;&nbsp;&nbsp;nproc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 50<br/>#ftp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hard&nbsp;&nbsp;&nbsp;&nbsp;nproc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0<br/>#@student&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxlogins&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4<br/>limits.conf的工作原理： <br/>limits.conf的后端是这样工作的：limits.conf是pam_limits.so的设置文件，然后/etc/pam.d/下的应用程式调用pam_***.so模块。譬如说，当用户访问服务器，服务程式将请求发送到PAM模块，PAM模块根据服务名称在/etc/pam.d目录下选择一个对应的服务文件，然后根据服务文件的内容选择具体的PAM模块进行处理。 <br/>例：限制admin用户登录到sshd的服务不能超过2个 <br/>在/etc/pam.d/sshd 中添加 session required pam_limits.so <br/>在/etc/security/limits.conf中添加 admin - maxlogins 2 <br/>查看应用程式能否被PAM支持，用ldd<br/>max_connections = 120<br/>mysql&gt; SHOW VARIABLES like &#039;%max_connections%&#039;;<br/>+-----------------+-------+<br/>&#124; Variable_name&nbsp;&nbsp; &#124; Value &#124;<br/>+-----------------+-------+<br/>&#124; max_connections &#124; 120&nbsp;&nbsp; &#124;<br/>+-----------------+-------+<br/>ysql&gt; SHOW VARIABLES LIKE &#039;open%&#039;;<br/>+------------------+-------+<br/>&#124; Variable_name&nbsp;&nbsp;&nbsp;&nbsp;&#124; Value &#124;<br/>+------------------+-------+<br/>&#124; open_files_limit &#124; 300&nbsp;&nbsp; &#124;<br/>+------------------+-------+<br/>root@192.168.225.128:/data0/data# ulimit -n<br/>1024<br/> Could not increase number of max_open_files to more than 1024 (request: 1210)<br/>接着查看MySQL的open_files_limit为1024,如下：<br/>mysql&gt; SHOW VARIABLES LIKE &#039;open%&#039;;<br/> +------------------+-------+<br/> &#124; Variable_name&nbsp;&nbsp;&nbsp;&nbsp;&#124; Value &#124;<br/> +------------------+-------+<br/> &#124; open_files_limit &#124; 1024&nbsp;&nbsp;&#124;<br/> +------------------+-------+<br/> 1 row IN SET (0.00 sec)<br/>在/etc/my.cnf加入open_files_limit=8192后重启MySQL后查看不起作用<br/>接着查看了下系统默认的打开文件数<br/>ulimit -n<br/>1024<br/>在/etc/security/limits.conf添加,重启生效:<br/>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; soft&nbsp;&nbsp;&nbsp;&nbsp;nofile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8192<br/>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hard&nbsp;&nbsp;&nbsp;&nbsp;nofile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8192<br/><textarea name="code" class="html" rows="15" cols="100">
ulimit -HSn 16666 
</textarea><br/>用ulimit -HSn 16666 修改只对当前的shell有效，退出后失效：<br/>重新登录并重启MySQL后查看<br/>ulimit -n<br/>8192<br/>SHOW VARIABLES LIKE &#039;open%&#039;;<br/> +------------------+-------+<br/> &#124; Variable_name&nbsp;&nbsp;&nbsp;&nbsp;&#124; Value &#124;<br/> +------------------+-------+<br/> &#124; open_files_limit &#124; 8192&nbsp;&nbsp;&#124;<br/> +------------------+-------+<br/> 1 row IN SET (0.00 sec)<br/>再次跑程序异常消失。<br/><br/><br/><br/>Was getting the following error after restarted MySQL:<br/>cat /proc/sys/fs/file-max<br/>48546<br/><br/>[Warning] Could not increase number of max_open_files to more than 1024 (request: 2158)<br/>The cause is that the operating system hard limit of &quot;open files&quot; was exceeded. Check for soft limit and the hard limit<br/><br/># ulimit -Sa &#124; grep &quot;open files&quot;<br/>open files (-n) 1200<br/># ulimit -Ha &#124; grep &quot;open files&quot;<br/>open files (-n) 1200<br/>In<br/>/etc/mysql/my.cnf<br/>, I&#039;ve increased the parameters so that table cache will utilize the memory instead of created on disk.<br/><br/>open_files_limit = 2048<br/>table_cache = 1024<br/>Edit<br/>/etc/security/limits.conf<br/>and restart your OS to take effect.<br/><br/>mysql hard nofile 8192<br/>mysql soft nofile 2400<br/><br/><br/><br/>理解max_open_files，max_connections，table_cache三者之间关系:<br/>转载自 arloe<br/>最终编辑 arloe<br/>今天亿次客MYSQL测试服务器突然挂了，查看日志原来有以下错误：<br/>Changed limits: max_open_files: 2048 max_connections: 1024 table_cache: 507<br/>后来提高以上相关参数，重新启动后，又出现以下错误<br/>Could not increase number of max_open_files to more than 2048<br/>看来问题没有找到...<br/>后来从网上才找到真正原因，以上三个参数有以下一定函数关系<br/>table_cache * 2 + max_connections＝max_open_files<br/>以上是大约关系，不能绝对等于。<br/>而WINDOWS的max_open_files最大值是2048，所以其它两个参数受制于2048.<br/>那么如何提高，WINDOWS下max_open_files最大值是2048？<br/>从网上查到，相关信息如下，具体怎么做，还没有搞清<br/>//////////////////////////////<br/>ulimit -n<br/>ulimit 可以查看每個 shell 的使用資源大小，-n 參數在 man page 中是寫 The maximum number of open file descriptors，換句話說，mysql 所處的 shell，真的能開的檔案只是 ulimit -n 的值，在我的系統上 ulimit -n 的值僅有 2048，所以就算 fs.file-max 有幾十萬，mysql shell 可以開的就是 2048 而已，這才是關鍵所在<br/>//////////////////////////////<br/>Tags - <a href="http://jackxiang.com/tags/mysql/" rel="tag">mysql</a>
]]>
</description>
</item><item>
<link>http://jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] mysql非root启动解除文件句柄的1024限制的注意事项]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>