如題,本章主要講下當伺服器出現 ERROR 1040: Too many connections
錯誤時的一些處理心得。
max_connections檢視
## 檢視最大連線數 SHOW VARIABLES LIKE "max_connections"; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_connections | 512 | +-----------------+-------+ ## 檢視已使用最大連線數 SHOW VARIABLES LIKE 'Max_used_connections'; +----------------------+-------+ | Variable_name | Value | +----------------------+-------+ | Max_used_connections | 499 | +----------------------+-------+
處理方案
這個問題一般有兩種處理方案,解決方案非常容易,我們只需要增加max_connections
連線數即可。
增加當前會話的mysql最大連線數
SET GLOBAL max_connections = 1000;
上面mysql連線值臨時增加到1000,但僅適用於當前會話。一旦我們重新啟動mysql服務或重新啟動系統,該值將重置為預設值。
永久增加mysql最大連線數
為了永久增加mysql連線數,我們需要編輯mysql配置檔案,即/etc/my.cnf
。
sudo vim /etc/my.cnf
## 修改 max_connections = 1000
儲存檔案重啟MySQL即可生效。
擴多少合適?
Max_connextions
並不是越大越好的,那麼如何配置?
方式一
對於提高MySQL的併發,很大程度取決於記憶體,官方提供了一個關於innodb
的記憶體計算方式:
innodb_buffer_pool_size + key_buffer_size + max_connections * (sort_buffer_size + read_buffer_size + binlog_cache_size) + max_connections * 2MB
方式二
安裝比例擴容:
max_used_connections / max_connections * 100% = [85, 90]%
最大使用連線數/最大連線數
達到了80%~90%區間,就建議進行優化或者擴容了。
擴充套件
以下也涉及幾種常見的影響MySQL效能的情況:
執行緒
SHOW STATUS LIKE 'Threads%'; +-------------------+--------+ | Variable_name | Value | +-------------------+--------+ | Threads_cached | 1 | | Threads_connected | 217 | | Threads_created | 29 | | Threads_running | 88 | +-------------------+--------+ SHOW VARIABLES LIKE 'thread_cache_size'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | thread_cache_size | 10 | +-------------------+-------+
- Threads_cached 執行緒在快取中的數量
- Threads_connected 當前開啟的連線數
- Threads_created 建立用於處理連線的執行緒數。
- Threads_running 未休眠的執行緒數
如果Threads_created大,則可能要增加thread_cache_size值。快取未命中率可以計算為Threads_created / Connections
檢視錶鎖情況
SHOW GLOBAL STATUS LIKE 'table_locks%'; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | Table_locks_immediate | 90 | | Table_locks_waited | 0 | +-----------------------+-------+
- Table_locks_immediate 立即獲得表鎖請求的次數
- Table_locks_waited 無法立即獲得對錶鎖的請求的次數,需要等待。這個值過高說明效能可能出現了問題,並影響連線的釋放
慢查詢
show variables like '%slow%'; +---------------------------+----------------------------------------------+ | Variable_name | Value | +---------------------------+----------------------------------------------+ | slow_launch_time | 2 | | slow_query_log | On | +---------------------------+----------------------------------------------+
執行緒詳情
## 檢視每個執行緒的詳細資訊 SHOW PROCESSLIST; +--------+----------+------------------+--------------+---------+-------+-------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +--------+----------+------------------+--------------+---------+-------+-------------+------------------+ | 3 | xxxadmin | localhost | NULL | Sleep | 1 | cleaning up | NULL | | 4 | xxxadmin | localhost | NULL | Sleep | 0 | cleaning up | NULL | | 5 | xxxadmin | localhost | NULL | Sleep | 6 | cleaning up | NULL | +--------+----------+------------------+--------------+---------+-------+-------------+------------------+
總結
當然,以上只是一個大概的解決思路,無論使用哪一種方式,都需要結合實際業務場景去擴容。
另外,對於生產環境,設定恰當的告警閾值,也是很有必要的。
最後,在程式設計時,由於用MySQL語句呼叫資料庫執行SQL
,會分配一個執行緒操作MySQL,所以在結束呼叫後,需要回收連線,避免洩漏。
參考文章
https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_max_connections
https://dev.mysql.com/doc/refman/5.7/en/server-status-variables.html
https://dev.mysql.com/doc/refman/8.0/en/memory-use.html