mysql非root启动解除文件句柄的1024限制的注意事项

jackxiang 2010-8-25 10:17 | |
mysql非root启动解除文件句柄的1024限制的注意事项

问题描述:couldn't increase number of open files to more than 1024
/usr/sbin/mysqld: Can't open file: './xxxx/xxxx.frm' (errno: 24)

如果非root启动时不修改最大句柄数,启动日志就会出现:
: Can't open file: '.\database\certain_table.frm' (errno: 24)
查询原因:
[~]# perror 24
OS error code  24:  Too many open files
待到句柄数耗光时,就会出现:
导致mysql无法应答新连接。
规避方法:
在root下修改ulimit后(比如ulimit -HSn 16666 ),
不能"su -" 或者"exit"到普通用户, 需要用su 到普通用户,否则修改的ulimit无效,导致句柄还是会不够用。
关于修改可打开最大文件句柄数,针对不同的linux系统有不同的方案



由於最近在 mysql 上面安裝了一些系統,導致 DB 裡的 table 量大增,突然有一天 mysql 自己就掛點了,看了 log 後發現訊息如下:
[ERROR] /usr/sbin/mysqld: Can't open file: './xxxx/xxxx.frm' (errno: 24)
.............................................
[ERROR] /usr/sbin/mysqld: Can't open file: './xxxx/xxxx.frm' (errno: 24)
[ERROR] Error in accept: Too many open files
[ERROR] Error in accept: Too many open files

網路上的討論有很多,包括調整系統本身的 fs.file-max 大小,還有在 /etc/my.cnf 中加入 open_files_limit 的設定值,但是實際上,光是這樣的調整是不夠或方向是不對的,因為 mysql 要開多少的 files,真正相關的不只這些設定。


相關的設定有:


/proc/sys/fs/file-max
這是系統資源配置的最高檔案數,設定值與記憶體大小有關,早期 ram 很貴的時代,這個值通常不會太大,所以 mysql 開的檔案數如果太多,確實可能被這個值限制住,但是現在動輒數 G 的 memory,這個值在我的 linux 系統上都內定開到 20 萬以上,因此問題不在這個值。 (若真想修改這個值,可以用 sysctl -w fs.file-max=##### 來修改,但系統重開後自動改回,可寫入 /etc/rc.local 開機執行)


ulimit -n
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 而已,這才是關鍵所在。


my.cnf 中的 table_cache, max_connections, open_files_limit 三個參數
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)
max_connections: 最高連線數。 (default: 100)
open_files_limit: mysqld 開啟的最高檔案數。 (default: 0)


理論上 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,那應該是要看這個值的大小設定。


問題來了,那個函式怎麼算的,一般說法是 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 掛點了。


仔細一看 log 後更可以進一步發現這個 [Warning] Could not increase number of max_open_files to more than 1024 (request: 2208)。


換句話說,如果 table_cache * 2 + max_connections 超過 1024 就會有警告,而 1024 便是 ulimit -n 那個 1024,即 shell 的限定使用資源。因此 mysql 真正會掛的主因是,它認為可以開到 2208 個檔,但系統只給它開到 1024 個檔,所以 mysql 就會一直去開第 1025 個檔而失敗,最後 mysql 就掛了.......


結論就是,不管我們要將我們的 mysql 設置 open_files_limit 或是使用 table_cache * 2 + max_connections,都應該要注意 ulimit -n 的值才是正解,跟 fs.file-max 關連反而較小了。


PS: 要查看 mysql 開啟的 files 數,可先用 ps aux | grep mysql 看 mysql PID,再利用 lsof -p PID# | wc -l 來統計。







/etc/security/limits.conf
#<domain>      <type>  <item>         <value>
#
#*               soft    core            0              禁止创建core文件
#*               hard    rss             10000     非root用户最多使用10M内存
#@student        hard    nproc        20     最多进程数限制在20
#@faculty        soft    nproc           20
#@faculty        hard    nproc           50
#ftp             hard    nproc           0
#@student        -       maxlogins       4
limits.conf的工作原理:
limits.conf的后端是这样工作的:limits.conf是pam_limits.so的设置文件,然后/etc/pam.d/下的应用程式调用pam_***.so模块。譬如说,当用户访问服务器,服务程式将请求发送到PAM模块,PAM模块根据服务名称在/etc/pam.d目录下选择一个对应的服务文件,然后根据服务文件的内容选择具体的PAM模块进行处理。
例:限制admin用户登录到sshd的服务不能超过2个
在/etc/pam.d/sshd 中添加 session required pam_limits.so
在/etc/security/limits.conf中添加 admin - maxlogins 2
查看应用程式能否被PAM支持,用ldd
max_connections = 120
mysql> SHOW VARIABLES like '%max_connections%';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 120   |
+-----------------+-------+
ysql> SHOW VARIABLES LIKE 'open%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| open_files_limit | 300   |
+------------------+-------+
root@192.168.225.128:/data0/data# ulimit -n
1024
Could not increase number of max_open_files to more than 1024 (request: 1210)
接着查看MySQL的open_files_limit为1024,如下:
mysql> SHOW VARIABLES LIKE 'open%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| open_files_limit | 1024  |
+------------------+-------+
1 row IN SET (0.00 sec)
在/etc/my.cnf加入open_files_limit=8192后重启MySQL后查看不起作用
接着查看了下系统默认的打开文件数
ulimit -n
1024
在/etc/security/limits.conf添加,重启生效:
*               soft    nofile          8192
*               hard    nofile          8192

用ulimit -HSn 16666 修改只对当前的shell有效,退出后失效:
重新登录并重启MySQL后查看
ulimit -n
8192
SHOW VARIABLES LIKE 'open%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| open_files_limit | 8192  |
+------------------+-------+
1 row IN SET (0.00 sec)
再次跑程序异常消失。



Was getting the following error after restarted MySQL:
cat /proc/sys/fs/file-max
48546

[Warning] Could not increase number of max_open_files to more than 1024 (request: 2158)
The cause is that the operating system hard limit of "open files" was exceeded. Check for soft limit and the hard limit

# ulimit -Sa | grep "open files"
open files (-n) 1200
# ulimit -Ha | grep "open files"
open files (-n) 1200
In
/etc/mysql/my.cnf
, I've increased the parameters so that table cache will utilize the memory instead of created on disk.

open_files_limit = 2048
table_cache = 1024
Edit
/etc/security/limits.conf
and restart your OS to take effect.

mysql hard nofile 8192
mysql soft nofile 2400



理解max_open_files,max_connections,table_cache三者之间关系:
转载自 arloe
最终编辑 arloe
今天亿次客MYSQL测试服务器突然挂了,查看日志原来有以下错误:
Changed limits: max_open_files: 2048 max_connections: 1024 table_cache: 507
后来提高以上相关参数,重新启动后,又出现以下错误
Could not increase number of max_open_files to more than 2048
看来问题没有找到...
后来从网上才找到真正原因,以上三个参数有以下一定函数关系
table_cache * 2 + max_connections=max_open_files
以上是大约关系,不能绝对等于。
而WINDOWS的max_open_files最大值是2048,所以其它两个参数受制于2048.
那么如何提高,WINDOWS下max_open_files最大值是2048?
从网上查到,相关信息如下,具体怎么做,还没有搞清
//////////////////////////////
ulimit -n
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 而已,這才是關鍵所在
//////////////////////////////

作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/3433/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!

Tags:

最后编辑: jackxiang 编辑于2012-2-26 13:31
评论列表
发表评论

昵称

网址

电邮

打开HTML 打开UBB 打开表情 隐藏 记住我 [登入] [注册]