ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
表示客戶端連線建立階段就中斷,尚未進入認證流程。常見於連線建立時的網路、配置、資源問題。
# 檢查服務狀態
systemctl status mysqld
# 或
service mysql status
# 重啟嘗試
systemctl restart mysqld
# 查看當前連線
SHOW STATUS LIKE 'Threads_connected';
SHOW VARIABLES LIKE 'max_connections';
# 臨時調大(需重啟永久生效)
SET GLOBAL max_connections = 1000;
長連線洩漏、連線池配置過大、慢查詢堵塞均會導致連線耗盡。
# 伺服器端檢查
iptables -L -n | grep 3306
firewall-cmd --list-ports
ufw status
# 客戶端測試連通性
telnet db_host 3306
nc -zv db_host 3306
nmap -p 3306 db_host
# my.cnf 檢查
[mysqld]
bind-address = 0.0.0.0 # 監聽所有介面
# bind-address = 127.0.0.1 # 僅本機(遠程無法連線)
# 修改後必須重啟
systemctl restart mysqld
[mysqld]
skip-name-resolve=1
# 禁用主機名解析,避免 DNS 卡住導致連線超時
# 注意:授權表 Host 欄位不能用主機名,需用 IP
# 客戶端強制無 SSL
mysql -u user -p --ssl-mode=DISABLED
# 或伺服器端暫時關閉 SSL
[mysqld]
require_secure_transport=OFF
dmesg | grep -i kill 檢查記憶體不足殺進程df -h 檢查 datadir 磁碟空間SHOW PROCESSLIST 分析--default-auth=mysql_native_passwordcaching_sha2_password vs mysql_native_passwordSET GLOBAL general_log = 1;
SET GLOBAL general_log_file = '/var/log/mysql/general.log';
SET GLOBAL log_output = 'FILE';
-- 重現錯誤後
SET GLOBAL general_log = 0;
-- 分析 /var/log/mysql/general.log
[mysqld]
log_error = /var/log/mysql/error.log
log_error_verbosity = 3 -- 1=錯誤, 2=警告, 3=資訊
# 伺服器端抓包
tcpdump -i eth0 -nn -s0 -w mysql.pcap port 3306
# Wireshark 分析:查看 TCP 三向交握、TLS 握手、MySQL 協定封包
| 參數 | 建議值 | 說明 |
|---|---|---|
| 最大連線數 | max_connections * 0.8 | 留餘量給管理連線 |
| 連線存活檢查 | testOnBorrow=true / validationQuery="SELECT 1" | 借用前驗證 |
| 空閒回收 | minEvictableIdleTimeMillis=300000 (5分) | 避免殭屍連線 |
| 連線超時 | connectionTimeout=10000 (10秒) | 快速失敗 |
| 重試機制 | 指數退避重試 3 次 | 應對瞬間抖動 |
# Python (SQLAlchemy + pool_pre_ping)
engine = create_engine(
'mysql+pymysql://user:pass@host/db',
pool_size=20,
max_overflow=10,
pool_pre_ping=True, # 關鍵:借用前 ping
pool_recycle=3600, # 1小時回收,防 MySQL wait_timeout 斷開
pool_timeout=30
)
# Java (HikariCP)
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://host:3306/db?useSSL=false");
config.setMaximumPoolSize(20);
config.setConnectionTimeout(10000);
config.setIdleTimeout(300000);
config.setMaxLifetime(600000);
config.setConnectionTestQuery("SELECT 1");
config.setPoolName("MySQL-Pool");
| 場景 | 典型原因 | 解決方案 |
|---|---|---|
| 應用啟動偶發報錯 | MySQL 尚未就緒 / 連線池初始化競態 | 啟動順序依賴、健康檢查重試、延遲初始化 |
| 長時間閒置後首請求失敗 | 連線被 MySQL wait_timeout 斷開 (預設 8h) | pool_pre_ping / pool_recycle < wait_timeout / validationQuery |
| 高併發下大量報錯 | max_connections 不足 / 連線洩漏 | 調大 max_connections、修復洩漏、限流熔斷 |
| Docker 容器間連線失敗 | 網路模式/服務名解析/bind-address | 同網絡、用服務名、bind-address=0.0.0.0 |
| 雲資料庫 (RDS/CloudSQL) 連線失敗 | 安全組/私有網路/SSL 強制/代理限制 | 檢查 VPC/SG、啟用 SSL、使用雲代理 |
Threads_connected / max_connections > 80% 告警Aborted_connects 突增告警Threads_created / Connections > 0.1 需調大 thread_cache_sizeSlow_queries + Threads_running 異常高系統化排查:從網路通達 → 服務狀態 → 配置參數 → 資源限制 → 客戶端配置,逐層驗證,多數情況在前 3 項即可解決!