程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> mysql中有大量sleep進程的原因與解決辦法

mysql中有大量sleep進程的原因與解決辦法

編輯:MySQL綜合教程

mysql中有大量sleep進程的原因與解決辦法   mysql服務器中有大量的sleep進程,本文分析下mysql出現大sleep進程原因分析與解決方法。   可能的原因:   造成睡眠連接過多的原因?   1. 使用了太多持久連接(個人覺得,在高並發系統中,不適合使用持久連接)   2. 程序中,沒有及時關閉mysql連接   3. 數據庫查詢不夠優化,過度耗時。   當然,更根本的方法,還是從以上三點排查之:   1. 程序中,不使用持久鏈接,即使用mysql_connect而不是pconnect。   2. 程序執行完畢,應該顯式調用mysql_close   3. 只能逐步分析系統的SQL查詢,找到查詢過慢的SQL,優化之p   我是用排除法去定位問題,對於此原因,1和3通過分析,發現根本不滿足   此處先排除是mysql 配置的問題,sleep的關閉時間是8個小時,默認值(show variables like 'wait_timeout';),並且服務器配置都是運維人員維護,我們的運維還是很出色的   排除1:   我的業務,php鏈接mysql並沒有使用持久鏈接 mysql_pconnect,高並發系統框架中,都不會用持久鏈接的   排除3:   數據庫查詢不夠優化?自己寫的,不能夠。如果真的有不夠不夠優化的sql,可以開啟mysql慢查詢日志查看,並優化之;還有一點就是我的這個業務通過看數據庫昨日、今日兩天的訪問情況,讀寫都不是很多,表的數據量只有二百多萬條,而且已經線上正常運營了很久,假如有不夠優化的查詢,早就掛了。   那問題只有可能是 2 程序中,沒有及時關閉mysql連接, 造成這個問題的原因很多,也很難分析。一般只要是框架裡,都會即時關閉mysql鏈接的(mysql_close),頁面訪問完,mysql鏈接必然會自動關閉。   例子:

[php] 
<?php  
define('MAX_SLEEP_TIME', 120);  
  
$hostname = "localhost";  
$username = "root";  
$password = "password";  
  
$connect = mysql_connect($hostname, $username, $password);  
$result = mysql_query("SHOW PROCESSLIST", $connect);  
while ($proc = mysql_fetch_assoc($result)) {  
if ($proc["Command"] == "Sleep" && $proc["Time"] > MAX_SLEEP_TIME) {  
@mysql_query("KILL " . $proc["Id"], $connect);  
}  
} //by www.jbxue.com  
mysql_close($connect);  
?>
將當中的$password 改成你實際的數據庫密碼,sleep連接的時間也可以修改,然後加入計劃任務就可以了。比如用 crontab -e 命令加入:
[html] 
*/2 * * * * php /usr/local/sbin/kill-mysql-sleep-proc.php  
就可以每隔 2 分鐘檢查並清除一次數據庫中的sleep連接了   如果你沒有修改過MySQL的配置,缺省情況下,wait_timeout的初始值是28800   wait_timeout過大有弊端,其體現就是MySQL裡大量的SLEEP進程無法及時釋放,拖累系統性能,不過也不能把這個值設置的過小,否則你可能會遭遇到“MySQL has gone away”之類的問題,通常來說,我覺得把wait_timeout設置為10是個不錯的選擇,但某些情況下可能也會出問題,比如說有一個CRON腳本,其中兩次SQL查詢的間隔時間大於10秒的話,那麼這個設置就有問題了(當然,這也不是不能解決的問題,你可以在程序裡時不時mysql_ping一下,以便服務器知道你還活著,重新計算wait_timeout時間):
[html] 
# vi /etc/my.cnf  
[mysqld]  
wait_timeout=10  
# /etc/init.d/mysql restart  
不過這個方法太生硬了,線上服務重啟無論如何都應該盡可能避免,看看如何在MySQL命令行裡通過SET來設置:
[html] 
mysql> set global wait_timeout=10;  
mysql> show global variables like '%timeout';  
+----------------------------+-------+  
| Variable_name | Value |  
+----------------------------+-------+  
| wait_timeout | 10 |  
+----------------------------+-------+  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved