1. 程式人生 > >mysql開啟檔案數用光的一次經歷

mysql開啟檔案數用光的一次經歷

昨天經歷了一次mysql災難,mysqld開啟檔案數用光,導致一系列問題的發生。

一開始是頁面打不開,觀察web伺服器,apache進城掛住,顯然是連線db出問題了,再看mysql,mysql登入,並沒有如以前順暢的登入顯示提示符,而是卡著不動,等了半天,終於進去了。

輸入show processlist;thread數正常,幾乎沒有sql語句在執行;

系統console下top,load正常,這下有點瞎,web和db伺服器負擔都挺小的啊,怎麼就卡住不動了呢???

mysql下輸入show global status like 'open%';

顯示:

+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| Open_files               | 8190|
| Open_streams             | 0      |
| Open_table_definitions   | 520    |
| Open_tables              | 902   |
| Opened_files             | 808671 |
| Opened_table_definitions | 6872   |
| Opened_tables            | 7573   |
+--------------------------+--------+
其中Open_files               | 8190,終於找到問題,啟動設定中open_files_limit為8192

這下原因就明白了,mysqld開啟的檔案控制代碼數超出了open_files_limit,而建立db連線都需要新的檔案控制代碼(網路連線也算)。

這時候就有新的疑問,為什麼打開了這麼多檔案,但是幾乎沒有thread在執行sql語句呢,當時沒搞懂,後來問了同事,得到了答案:

show variables like 'table_open_cache';

| table_open_cache             | 1024            

再看| Open_tables              | 902   |

902<1024,所以mysql不會自動回收這些開啟的控制代碼,即使這些控制代碼對應的thread不在執行任何東西。

解決方案:

set global table_open_cache=800;

配置的不恰當導致了一個沒法解決的問題,悲劇啊。

ps:打開了902個table卻有8190個files是因為部分表使用了分割槽,這樣開啟一個表就需要開啟很多檔案,下一步需要優化一下分割槽,把大小為0的分割槽刪除,並且合併較小的分割槽。