標籤:
錯誤資訊如下:
.....150905 13:10:17 [ERROR] /usr/local/mysql/bin/mysqld: Can‘t open file: ‘./mytest/t1.frm‘ (errno: 24)150905 13:10:17 [ERROR] /usr/local/mysql/bin/mysqld: Can‘t open file: ‘./mytest/t2.frm‘ (errno: 24)......150905 13:10:17 [ERROR] Error in accept: Too many open files....
注意到, 系統錯誤代號是 24, 用 perror 來查看一下具體的錯誤資訊是什麼:
[[email protected]]# /usr/local/mysql/bin/perror 24OS error code 24: Too many open files
原來是開啟檔案太多了, 好辦.用sysctl來調整一下就好了:
[[email protected]]# sysctl -w fs.file-max=43621[[email protected]]# sysctl -a | grep fs.file-maxfs.file-max = 43621
最後, 還有最重要的一點是, 修改 mysqld 的設定檔 my.cnf, 增加如下一行:
open_files_limit = 4096 #根據自己的情況適當調整,系統預設值是 # max_connections*5 或 max_connections + table_cache*2
然後, 以root身份重新啟動 mysqld. 在這裡, 儘管 my.cnf 中指定的運行使用者不是root, 一樣可以以root身份來啟動mysqld, 否則 open_files_limit 選項無法生效, 因為核心限制了普通使用者的最多開啟檔案數.
目前open file超過limit的問題:
除了socket,binlog, relay log, ibdata, logfile等這些固定需要開啟的控制代碼以外,
剩下的各種儲存引擎的資料檔案的開啟數量,只應該和即時的IO並發請求量有關係,和使用者的請求, 壓力, 多少張表沒有什麼關係。
所以,出現的open file太多的問題,屬於代碼缺陷, 目前集中在Myisam和tukodb引擎:
InnoDB引擎嚴格按照Innodb_open_files的設定,使用LRU管理open file,不會遇到這個問題。
flush tables,其實沒有關閉檔案的含義,只是mysiam的handler close介面剛好會嘗試關閉MYD,MYI檔案, 這個操作對InnoDB表並沒有什麼卵用。
分區表過多,也是屬於myisam表的缺陷,分區多少也應該和open file數量沒什麼關係。
如何查看mysqld進程開啟的檔案數?
假設pid = 26206
ls /proc/26206/fd | wc -l
在MySQL中,有幾個地方會存在檔案描述符限制:
1、在Server層,整個mysqld執行個體開啟檔案總數超過使用者進程級的檔案數限制,需要檢查核心 fs.file-max 限制、進程級限制 ulimit -n 及MySQL中的 open-files-limit 選項,是否有某一個超限了。任何一個條件超限了,就會拋出錯誤。
2、雖然Server層總檔案數沒有超,但InnoDB層也有限制,所有InnoDB相關檔案開啟總數不能超過 innodb-open-files 選項限制。否則的話,會先把最早開啟的InnoDB檔案描述符關閉,才能開啟新的檔案,但不會拋出錯誤,只有警示資訊。
相應地,如果提示超出限制,則可以使用下面方法提高上限:
1、首先,提高核心級總的限制。執行:sysctl -w fs.file-max=3264018;2、其次,提高核心對使用者進程級的開啟檔案數限制。執行:ulimit -n 204800;3、最後,適當提高MySQL層的幾個參數:open-files-limit、innodb-open-files、table-open-cache、table-definition-cache。
1、open-files-limit
它限制了mysqld進程可持有的最大開啟檔案數,相當於是一個小區的總電閘,一旦超限,小區裡所有住戶都得停電。
5.6.7(含)以前,預設值0,最大和OS核心限制有關;
5.6.8(含)以後,預設值會自動計算,最大和OS核心限制有關。
在5.6.8及以後,其自動計算的幾個限制規則見下,哪個計算結果最大就以哪個為上限:
1) 10 + max_connections + (table_open_cache * 2)2) max_connections * 53) open_files_limit value specified at startup, 5000 if none
2、innodb-open-files
限制InnoDB引擎中資料表空間檔案最大開啟的數量,相當於自己家中電箱裡的某個電路保險,該電路短路的話,會自動跳閘,而不會影響其他電路,去掉短路源後重新按上去就可以使用。
其值最低20,預設400,只計算了包含ibdata*、ib_logfile*、*.ibd 等三類檔案,redo log不計算在內,5.6以後可獨立undo log,我還未進行測試,應該也不會被計算在內,有興趣的朋友可驗證下。
3、table-definition-cache
該cache用於緩衝 .frm 檔案,該選項也預示著 .frm 檔案同時可開啟最大數量。
5.6.7 以前預設值400;
5.6.7 之後是自動計算的,且最低為400,自動計算公式:400 + (table-open-cache / 2)。
對InnoDB而言,該選項只是軟性限制,如果超過限制了,則會根據LRU原則,把舊的條目刪除,加入新的條目。
此外,innodb-open-files 也控制著最大可開啟的表數量,和 table-definition-cache 都起到限制作用,以其中較大的為準。如果沒配置限制,則通常選擇 table-definition-cache 作為上限,因為它的預設值是 200,比較大。
4、table-open-cache
該cache用於緩衝各種所有資料表檔案描述符。
5.6.7 以前,預設值400,範圍:1 – 524288;
5.6.8 – 5.6.11,預設值2000,範圍:1 – 524288;
5.6.12以後,預設值2000(且能自動計算),範圍:1 – 524288。
補充說明1:關於如何計算表檔案描述符的建議:
table-open-cache 通常和 max-connections 有關係,建議設定為 max_connections * N,N的值為平均每個查詢中可能總共會用到的表數量,同時也要兼顧可能會產生暫存資料表。
補充說明2:MySQL會在下列幾種情況把表從table cache中刪掉:
1、table cache已滿,並且正要開啟一個新表時;2、table cache中的條目數超過 table_open_cache 設定值,並且有某些表已經長時間未訪問了;3、執行重新整理表操作時,例如執行 FLUSH TABLES,或者 mysqladmin flush-tables 或 mysqladmin refresh
補充說明3:MySQL採用下述方法來分配table cache:
1、當前沒在用的表會被釋放掉,從最近最少使用的表開始;
2、當要開啟一個新表,當前的cache也滿了且無法釋放任何一個表時,table cache會臨時加大,臨時加大的table cache中的表不用了之後,會被立刻釋放掉。
mysql open files