查看完整版本: MySQL too many open files - max open file 的解決方法


ppstream 2012-1-27 13:48

MySQL too many open files - max open file 的解決方法

文章為網路上截取,對於MySQL Open file分析的還不錯,故吸收後再分享給大家^^!!<br><br>由於最近在 mysql 上面安裝了一些系統,導致 DB 裡的 table 量大增,突然有一天 mysql 自己就掛點了,看了 log 後發現訊息如下:<br>[quote] <br>/usr/sbin/mysqld: Can’t open file: ‘./xxxx/xxxx.frm’ (errno: 24)<br>………………………………………<br>[ERROR] /usr/sbin/mysqld: Can’t open file: ‘./xxxx/xxxx.frm’ (errno: 24)<br>[ERROR] Error in accept: Too many open files<br>[ERROR] Error in accept: Too many open files<br>[/quote]<br>網路上的討論有很多,包括調整系統本身的 fs.file-max 大小,還有在 /etc/my.cnf 中加入 open_files_limit 的設定值,但是實際上,光是這樣的調整是不夠或方向是不對的,因為 mysql 要開多少的 files,真正相關的不只這些設定。<br><br>相關的設定有:<br><br><font style="color: DarkRed;" size="3">/proc/sys/fs/file-max</font><b><br></b>這是系統資源配置的最高檔案數,設定值與記憶體大小有關,早期 ram 很貴的時代,這個值通常不會太大,所以 mysql 開的檔案數如果太多,確實可能被這個值限制住,但是現在動輒數 G 的 memory,這個值在我的 linux 系統上都內定開到 20 萬以上,因此問題不在這個值。 (若真想修改這個值,可以用 sysctl -w fs.file-max=##### 來修改,但系統重開後自動改回,可寫入 /etc/rc.local 開機執行)<br><br><font style="color: DarkRed;" size="3"><b>ulimit -n</b></font><br>ulimit 可以查看每個 shell 的使用資源大小,-n 參數在 man page 中是寫 The maximum number of open file descriptors,換句話說,mysql 所處的 shell,真的能開的檔案只是 ulimit -n 的值,在我的系統上 ulimit -n 的值僅有 1024,所以就算 fs.file-max 有幾十萬,<font color="#ff0000">mysql shell 可以開的就是 1024 而已,這才是關鍵所在。</font><br><br><b>my.cnf 中的 table_cache, max_connections, open_files_limit 三個參數</b><br><b>table_cache</b>: 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><br><b>max_connections</b>: 最高連線數。 (default: 100)<br><br><b>open_files_limit</b>: mysqld 開啟的最高檔案數。 (default: 0)<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>問題來了,那個函式怎麼算的,一般說法是 table_cache * 2 + max_connections,我在 my.cnf 原本的設定是 table_cache 1024, max_connections 500, open_files_limits 則不設 (default: 0),結果計算出來是 1024 x 2 + 500 = 2548,所以照理論來說 mysql 可以開到 2548 個檔案。但實際卻在我 DB table 數大增後,便很容易因為文章一開頭的 error 讓 mysql 掛點了。<br><br>仔細一看 log 後更可以進一步發現這個 [Warning] Could not increase number of max_open_files to more than 1024 (request: 2548)。<br>換句話說,如果 table_cache * 2 + max_connections 超過 1024 就會有警告,而 1024 便是 ulimit -n 那個 1024,即 shell 的限定使用資源。因此 mysql 真正會掛的主因是,它認為可以開到 2548 個檔,但系統只給它開到 1024 個檔,所以 mysql 就會一直去開第 1025 個檔而失敗,最後 mysql 就掛了…….<br><br>結論就是,不管我們要將我們的 mysql 設置 open_files_limit 或是使用 table_cache * 2 + max_connections,<font style="color: DarkRed;" size="3">都應該要注意 ulimit -n 的值才是正解</font>,跟 fs.file-max 關連反而較小了。<br><br>PS: 要查看 mysql 開啟的 files 數,可先用 <br>(1) #ps aux | grep mysql 看 mysql PID<br>(2) 再利用 #lsof -p PID# | wc -l 來統計。<br><b><br>至於要怎麼使用 ulimit 來修改 max open file呢?</b><br><br>(1) 修改 /etc/bashrc ,在最下面加上一行<br>ulimit -HSn 32768<br><br>(2)另一種設定 max open file的方式:<br>修改 /home/adj/.bashrc,找個位置加入ulimit -HSn 32768<br>例如:要修改adj這個user 的 max open file,則修改 /home/adj/.bashrc 加入要設定的值即可。
頁: [1]
查看完整版本: MySQL too many open files - max open file 的解決方法