MySQL「Lost connection at reading authorization packet」排查實戰:網卡流量導致的連線異常
生產環境 PHP 間歇性報錯 Lost connection to MySQL server at 'reading authorization packet',本文記錄從現象切入、排查連線數/負載/DNS/skip-name-resolve,最終定位到**外網網卡帶寬飽和**導致握手包丟失的完整過程。
一、現象與初步排查
- 錯誤: Lost connection to MySQL server at 'reading authorization packet'
- 本地連線正常: 排除 MySQL 服務掛掉
SHOW PROCESSLIST 發現大量 unauthenticated user
二、關鍵線索分析
| 線索 | 分析 | 排查結果 |
| unauthenticated user | 客戶端發起連線,但未完成認證 | 非高並發、負載正常,非典型「認證緩慢」 |
| skip-name-resolve=ON | 已禁用 DNS 反向解析 | 排除 DNS 故障導致認證卡頓 |
| OS 監控:外網網卡百兆帶寬報警 | PHP 連 MySQL 走外網 IP,每秒數百 SELECT 佔滿帶寬 | **核心原因鎖定** |
三、根因還原
架構拓撲:
[PHP App Server] --(外網 IP, 百兆)--> [MySQL Server]
流量計算:
QPS 500 * 平均封包 2KB = 1MB/s ≈ 8Mbps
握手包 + 結果集雙向傳輸,突發佔滿 100Mbps
導致 TCP 握手包(authorization packet)丟包/重傳超時
客戶端收到「reading authorization packet」斷開
四、解決方案
- 立即生效: 應用配置改為 MySQL 內網 IP(千兆網卡)
- 根治: 架構層面禁用外網訪問資料庫,VPC/安全組隔離
- 驗證: 切換後連線錯誤消失,外網流量歸零,內網流量正常
五、同類問題診斷清單
1. 確認錯誤發生階段:握手階段 vs 查詢階段
- "reading authorization packet" = 握手/認證階段斷開
- "reading initial communication packet" = 連線建立前斷開
- "during query" = 查詢執行中斷開
2. 排查順序:
[ ] MySQL 服務存活?本地能連?
[ ] 連線數是否達上限?(SHOW VARIABLES LIKE 'max_connections'; SHOW STATUS LIKE 'Threads_connected';)
[ ] skip-name-resolve 是否開啟?(避免 DNS 阻塞)
[ ] 防火牆/安全組是否攔截?
[ ] 網絡層:ping 延遲、丟包率、帶寬使用率 (iftop/nload/sar -n DEV)
[ ] 客戶端驅動版本兼容性?(caching_sha2_password vs mysql_native_password)
3. 關鍵配置優化:
[mysqld]
skip-name-resolve=ON
max_connections=2000
connect_timeout=10
max_allowed_packet=64M
net_read_timeout=30
net_write_timeout=60
六、最佳實踐總結
- 資料庫絕不暴露外網: 僅內網/VPC 訪問,安全組最小權限
- 應用配置內網 IP/域名: 避免 NAT/公網繞行
- 啟用 skip-name-resolve: 消除 DNS 不確定性
- 監控網卡流量: 納入基礎設施監控體系,設定帶寬告警閾值
- 連線池配置: 合理設置
max_connections、wait_timeout、interactive_timeout
- 上一篇文章: MySQL 資料庫命名與設計規範:從 3NF 到工程落地的完整標準
- 下一篇文章: MySQL DELETE 使用別名報錯的正確寫法
Copyright ©
程式碼之家 All Rights Reserved