生產庫 CPU 突破 200%,慢查詢日誌(閾值 5s)卻無記錄。SHOW PROCESSLIST 發現大量 SELECT 處於 Writing to net 狀態,根因定位為 max_allowed_packet 默認 1MB 過小,導致大結果集網絡傳輸阻塞、線程堆積、CPU 飆升。
SHOW PROCESSLIST:多個 SELECT 狀態 Writing to net,Time 列持續增長EXPLAIN 顯示涉及表無索引/全表掃描,但數據量僅 2萬行,理論不應導致高 CPU線程正在將結果集通過網絡發送給客戶端。若客戶端讀取緩慢、網絡延遲高、或結果集超過 max_allowed_packet 導致分包重傳,線程會長時間停留在此狀態,佔用 CPU 處理網絡 I/O 邏輯。
SHOW GLOBAL VARIABLES LIKE 'max_allowed_packet'; -- 返回:1048576 (1MB,默認值)
業務查詢返回大文本/Blob 字段,單行超過 1MB,或結果集總量大,觸發分包機制,導致網絡交互頻繁、CPU 消耗異常。
SET GLOBAL max_allowed_packet = 134217728; -- 128MB -- 或 1073741824 (1GB,視業務最大單行/結果集而定)
[mysqld] max_allowed_packet = 128M # 建議 64M-256M,避免過大導致 OOM 風險
Writing to net 狀態消失,線程快速進入 Sleep 或結束Query_timemax_allowed_packet 限制 → 網絡阻塞 → CPU 飆升。補充索引後結果集縮小,問題緩解| 場景 | 建議值 | 備註 |
|---|---|---|
| 常規 Web 應用 | 16M - 64M | 覆蓋絕大多數業務 |
| 大文本/Blob 存儲 | 128M - 256M | 配合 innodb_log_file_size 調大 |
| 批量數據導出/同步 | 512M - 1G | 臨時調大,用完改回 |
net_buffer_length:初始網絡緩衝區(默認 16KB),大包場景可適當調大(如 64KB)slave_max_allowed_packet:從庫接收主庫 Binlog 事件的最大包(默認 1GB,通常無需改)maxAllowedPacket、Python max_allowed_packet 等需與服務端一致# 1. 確認當前值 mysql -e "SHOW GLOBAL VARIABLES LIKE 'max_allowed_packet';" # 2. 觀察 Writing to net 線程 mysql -e "SHOW PROCESSLIST;" | grep "Writing to net" # 3. 檢查網絡錯誤計數 mysql -e "SHOW GLOBAL STATUS LIKE 'Aborted_clients';" mysql -e "SHOW GLOBAL STATUS LIKE 'Aborted_connects';" # 4. 調整並驗證 mysql -e "SET GLOBAL max_allowed_packet=134217728;" # 觀察 CPU、線程狀態變化