mysql sleep進程 過多


如果你沒有修改過MySQL的配置,缺省情況下,wait_timeout的初始值是28800。


wait_timeout過大有弊端,其體現就是MySQL里大量的SLEEP進程無法及時釋放,拖累系統性能,不過也不能把這個指設置的過小,否則你可能會遭遇到“MySQLhas goneaway”之類的問題,通常來說,我覺得把wait_timeout設置為10是個不錯的選擇,但某些情況下可能也會出問題,比如說有一個CRON腳本,其中兩次SQL查詢的間隔時間大於10秒的話,那么這個設置就有問題了(當然,這也不是不能解決的問題,你可以在程序里時不時mysql_ping一下,以便服務器知道你還活着,重新計算wait_timeout時間):


# vi /etc/my.cnf


[mysqld]

wait_timeout=10


# /etc/init.d/mysql restart

不過這個方法太生硬了,線上服務重啟無論如何都應該盡可能避免,看看如何在MySQL命令行里通過SET來設置:


mysql> set global wait_timeout=10;


mysql> show global variables like'wait_timeout';

+----------------------------+-------+

| Variable_name            | Value |

+----------------------------+-------+

| wait_timeout             | 10   |

+----------------------------+-------+


這里一個容易把人搞蒙的地方是如果查詢時使用的是showvariables的話,會發現設置好像並沒有生效,這是因為單純使用show variables的話就等同於使用的是showsession variables,查詢的是會話變量,只有使用show globalvariables,查詢的才是全局變量。


網絡上很多人都抱怨說他們set global之后使用showvariables查詢沒有發現改變,原因就在於混淆了會話變量和全局變量,如果僅僅想修改會話變量的話,可以使用類似setwait_timeout=10;或者set session wait_timeout=10;這樣的語法。


另一個值得注意的是會話變量wait_timeout初始化的問題,這一點在手冊里已經明確指出了,我就直接拷貝了:


On thread startup, the session wait_timeout value isinitialized from the global wait_timeout value or from the globalinteractive_timeout value, depending on the type of client (asdefined by the CLIENT_INTERACTIVE connect option tomysql_real_connect()).


MySQL大拿Jeremy Zawodny曾在他的文章Fixing Poor MySQL DefaultConfigurationValues里面列出了幾個很惡心的MySQL缺省設置,不過沒包含wait_timeout,但我覺得它也應該算一個,每次新裝MySQL后最好都記得修改它。


參考文章2

睡眠連接過多,會對mysql服務器造成什么影響?


嚴重消耗mysql服務器資源(主要是cpu, 內存),並可能導致mysql崩潰。


造成睡眠連接過多的原因?


1. 使用了太多持久連接(個人覺得,在高並發系統中,不適合使用持久連接)


2. 程序中,沒有及時關閉mysql連接


3. 數據庫查詢不夠優化,過度耗時。


那么,如果要從根本上解決sleep連接過多,就得從以上三點反復檢查,但是見效並不快。


網上有人分享,使用shell腳本配合cron,定期殺死睡眠時間太久的連接,但是這種方法非常不可取,典型的以暴制暴,很可能導致數據崩潰,而且,還需要編寫相應shell,設置cron, 實施成本較繁瑣,不推薦使用。


那么更好的辦法應該是讓mysql自己決定這些睡眠連接的命運,實施會更簡單,有效。


mysql的配置文件中,有一項:


wait_timeout, 即可設置睡眠連接超時秒數,如果某個連接超時,會被mysql自然終止,多好的辦法!


如設置: 


wait_timeout=100#即設置mysql連接睡眠時間為100秒,任何sleep連接睡眠時間若超過100秒,將會被mysql服務自然終止,要比編寫shell腳本更簡單。


那么,對於正在運行中的生產服務器,在不能停止服務情況下,修改此項怎么辦?很簡單,以root用戶登錄到mysql,執行:


set global wait_timeout=100


即可。


在我的生產環境中,使用這個辦法,取得了相當好的效果。


當然,更根本的方法,還是從以上三點排查之:


1. 程序中,不使用持久鏈接,即使用mysql_connect而不是pconnect。


2.   程序執行完畢,應該顯式調用mysql_close


3. 只能逐步分析系統的SQL查詢,找到查詢過慢的SQL,優化之


PS: wait_timeout  設置為大於數據池執行心跳探雷的時間


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM