翻譯:MySQL Error: Too many connections 前言: 本文是對Muhammad Irfan的這篇博客MySQL Error: Too many connections的翻譯,如有翻譯不對或不好的地方,敬請指出,大家一起學習進步。尊重原創和翻譯勞動成果,轉載時請註明出處。謝... ...
翻譯:MySQL Error: Too many connections
前言: 本文是對Muhammad Irfan的這篇博客MySQL Error: Too many connections的翻譯,如有翻譯不對或不好的地方,敬請指出,大家一起學習進步。尊重原創和翻譯勞動成果,轉載時請註明出處。謝謝!
英文原文地址:https://www.percona.com/blog/2013/11/28/mysql-error-too-many-connections/
翻譯原文地址:www.cnblogs.com/kerrycode/p/8965151.html
我們總是在Percona Support上收到一些關於如何避免糟糕的“Too many connections”錯誤,以及參數max_connections的推薦值這樣一類問題。因此在這篇文章中,我盡最大的努力以最佳答案涵蓋這方面的問題,減少遇到同樣問題的人的困惑。
我的同事Aurimas寫了一篇關於通過GDB更改max_connections值的精彩文章,當MySQL服務正在運行時,無需重新啟動MySQL即可擺脫“Too many connections”錯誤 你可以點擊這兒查看文章詳細內容。
在MySQL 5.5中,預設的最大同時客戶端連接數為151 ,如果你達到了max_connections的限制,你再嘗試去連接MySQL伺服器時就會遇到“Too many connections"錯誤。這意味著所有可用的連接都在被其它客戶端使用。
MySQL在達到max_connections限制時,允許一個額外的具有SUPER許可權的連接連接到MySQL去診斷連接問題,通常來說,管理員用戶有SUPER許可權,你應該避免授予應用程式用戶(app users) SUPPER許可權。
MySQL的每一個客戶端連接使用一個線程,太多活動的線程都是資料庫的性能殺手,通常來說,一個大量高併發連接,併發執行大量查詢會導致明顯的性能下降,並且增加死鎖的風險。在MySQL 5.5之前,MySQL的擴展性不好,當然從這個版本之後它做的越來越好,但是如果你有數以百計的活動連接(不計算休眠(sleeping)狀態的連接)會導致使用記憶體的增長。每一個連接都會給線程分配線程緩存區(thread buffer),因此記憶體表胡要求跟多的記憶體滿足global buffers的要求, 重要的是每個連接都必須使用tmp_table_size/max_headp_table.儘管它們不會立即分給每個連接。
大多數情況下,連接數過多這個錯誤出現是因為應用程式的一些bug導致不能正確的關閉連接或者是錯誤的設計,例如那些已經建立的連接,但是在MySQL指針(句柄)關閉之前,一直在忙著做其他事情。在應用程式沒有正確的關閉連接的情況下, wait_timeout是一個重要的參數去優化或丟棄那些沒有使用或空閑的連接,將活動會話最大限度減少到最小數量。這最終將有助於避免“Too many connections”錯誤。 也有一些系統即使有大量連接線程,但是系統運行良好,大部分連接是空閑的,通常,休眠的線程不會占用太大記憶體- 512KB或更少, Threads_running是一個有價值的監視指標,當然它不包括休眠線程- 它表示當前活動的最大線程。而threads_connectionstaus變數表示所有連接的線程, Peter寫了一篇很好的文章發佈在這裡,你可以從這裡進一步查看詳細內容。
如果你在應用程式端使用連接池, max_connections 必須比接池的最大連接數要大。 使用連接池是一個可選的方案,如果你遇到了大量的連接,那麼max_connections的推薦設置是什麼呢? 這個沒有絕對答案,這個取決於可用的RAM總量以及每一個連接使用的記憶體數量,增加max_connections值會增加mysqld進程需要的文件描述符數量,註意:設置最大max_connections沒有硬性限制,所以,你必鬚根據你資料庫的負載合理設置max_connections的值,以及同時連接到MySQL的連接數量等,通常來講,太大的max_connections是不推薦使用的,因為那些激烈競爭的連接問題可能會引起在某些條件下的鎖定或性能下降, 如果活動連接使用臨時表或記憶體表,記憶體使用量會變得非常高,在那些記憶體較小的伺服器或那些應用程式端具有很多連接控制的系統上,我們應該使用較小的max_connection值,例如100-300, 16G RAM或更高記憶體的伺服器,設置max_connection=1000是一個較好的註意,當然,每個連接緩衝區應該具有良好的預設值,而在某些系統上,我們可以看到高達8k 最大的連接,但是這樣的系統在負載峰值時通常會性能下降。
為瞭解決這個問題,ORACLE和MariaDB團隊在MySQL內部實現了線程池(thread pool), Percona Server從MariaDB移植了此功能。它在Percona Server中的實現可以閱讀此鏈接。正確的配置線程池,至少對於某些類型的工作負載,您可能預期的吞吐量至少至多達數千個併發連接。
註意事項:請註意,在MySQL 5.6中,如果max_connections的值設置太高,會引起大量的記憶體分配,這個bug的報告在這裡http://bugs.mysql.com/bug.php?id=68514
結論:
沒有一個固定的規則為max_connectins的設置合適值,因為它取決於你資料庫的工作負載,考慮到每個連接的線程都需要分配記憶體以及昂貴的上下文切換,我建議根據你系統的負載選擇合適的max_connections數量,並儘量避免同時打開太多的連接,以便應用程式正常運行。
-------------------------------------------------------------分割線--------------------------------------------------------------
上面是翻譯部分,下麵關於MySQL的“Too many connections”有下麵三個問題,簡單彙總總結一下,如有不足或錯誤之處,敬請指正:
1:Too many connections 發生的場景?
1、應用程式的Bug或不合理設計。
1.1 沒有及時關閉資料庫連接或出現Bug(例如,迴圈裡面打開數據連接或 代碼裡面忘記關閉資料庫連接等等)。
1.2 在應用程式層沒有使用連接池。
....................
2、出現阻塞,導致大量連接被阻塞,在高併發的情況下導致連接數彪增。出現“Too many connections”
3、MySQL的連接對應一個線程,在慢查詢較多的情況下,導致線程數與連接數持續增長。
4、突發性業務彪增引起的。
2:如何避免Too many connections錯誤發生
1、 應用程式在完成數據相關操作後及時關閉連接。
2、 使用連接池(connection pool),有些版本可以使用線程池(MySQL企業版、MariaDB等)
3、 設置wait_timeout為一個合適的值,例如wait_timeout=10秒。減少大量空閑連接。
4、 監控資料庫阻塞情況,避免由於異常或特殊情況導致大量連接被阻塞。
5、 根據系統負載,合理設置max_connections的值,避免max_connections參數設置過小引起“MySQL Error: Too many connections”