如何處理MySQL經常出現CPU佔用率達到99%

淼淼之森發表於2019-07-25

如何處理MySQL經常出現CPU佔用率達到99%

情況說明:

最近在自己購買的linux伺服器上搗鼓了一個小專案,按理說不存在CPU佔用率會達到100%的情況,但事實就是經常出現。

然後,我第一反應是“臥槽,被人當礦機了?”,然後一頓查詢操作後,發現並沒有被人搗鼓,問題出現在mysql上,MySQL的CPU佔用率達到了100%;這是我就很納悶了,這麼小個程式,不應該啊。然後就開始了排查。

查詢了下sql程式,發現:

mysql> show processlist;
+-----+------+----------------------+-------------+---------+------+-------+------------------+
| Id  | User | Host                 | db          | Command | Time | State | Info             |
+-----+------+----------------------+-------------+---------+------+-------+------------------+
|   8 | root | 182.150.55.136:64138 | itresources | Sleep   | 16686 |       | NULL             |
|   18 | root | 182.150.55.136:65138 | itresources | Sleep   | 12886 |       | NULL             |
|   22 | root | 182.150.55.136:66138 | itresources | Sleep   | 14486 |       | NULL             |
|   11 | root | 182.150.55.136:67138 | itresources | Sleep   | 1116 |       | NULL             |
| 206 | root | localhost            | NULL        | Query   |    0 | NULL  | show processlist |
+-----+------+----------------------+-------------+---------+------+-------+------------------+
2 rows in set (0.00 sec)

發現MySQL上有大量的閒置連線。

解決措施:

MySQL伺服器所支援的最大連線數是有上限的,因為每個連線的建立都會消耗記憶體,因此我們希望客戶端在連線到MySQL Server處理完相應的操作後,應該斷開連線並釋放佔用的記憶體。如果你的MySQL Server有大量的閒置連線,他們不僅會白白消耗記憶體,而且如果連線一直在累加而不斷開,最終肯定會達到MySQL Server的連線上限數,這會報'too many connections'的錯誤。對於wait_timeout的值設定,應該根據系統的執行情況來判斷。在系統執行一段時間後,可以通過show processlist命令檢視當前系統的連線狀態,如果發現有大量的sleep狀態的連線程式,則說明該引數設定的過大,可以進行適當的調整小些。

 Mysql> show variables like '%timeout%';

+-----------------------------+----------+
| Variable_name              | Value    |
+-----------------------------+----------+
| connect_timeout            | 10      | 
| delayed_insert_timeout      | 300      | 
| innodb_flush_log_at_timeout | 1        | 
| innodb_lock_wait_timeout    | 50      | 
| innodb_rollback_on_timeout  | OFF      | 
| interactive_timeout        | 28800    | 
| lock_wait_timeout          | 31536000 | 
| net_read_timeout            | 30      | 
| net_write_timeout          | 60      | 
| slave_net_timeout          | 3600    | 
| wait_timeout                | 28800    | 
+-----------------------------+----------+

11 rows in set (0.00 sec)

經查詢發現原來mysql沒有進行過優化,還是原來的預設值:28800(即8個小時)

編輯 /etc/my.cnf 檔案,在mysqld 下 新增 timeout引數,設定為120秒,如下:

【mysqld】
wait_timeout=120
interactive_timeout=120

注意:要同時設定interactive_timeout和wait_timeout才會生效。

最後重啟一下mysql 生效 即可!

mysql> show variables like '%timeout%';
+----------------------------+----------+
| Variable_name              | Value    |
+----------------------------+----------+
| connect_timeout            | 10       |
| delayed_insert_timeout     | 300      |
| innodb_lock_wait_timeout   | 50       |
| innodb_rollback_on_timeout | OFF      |
| interactive_timeout        | 120      |
| lock_wait_timeout          | 31536000 |
| net_read_timeout           | 30       |
| net_write_timeout          | 60       |
| slave_net_timeout          | 3600     |
| wait_timeout               | 120      |
+----------------------------+----------+
10 rows in set (0.00 sec)

相關文章