線上系統因資料庫連接超時頻發,排查 my.cnf 後發現根因在應用代碼連接池配置。借此機會系統梳理 MySQL 12 個核心超時參數,釐清適用場景與常見誤區。
| 參數 | 默認值 | 作用範圍 | 核心含義 |
|---|---|---|---|
connect_timeout | 10s | 握手階段 | 等待客戶端發送握手包的時間,防惡意連接佔用槽位 |
wait_timeout | 28800s (8h) | 非交互式連接 (TCP/Socket) | 空閒連接最大存活時間,超過則斷開 |
interactive_timeout | 28800s (8h) | 交互式連接 (CLI/Workbench) | 帶 CLIENT_INTERACTIVE 標識的連接空閒斷開時間 |
net_read_timeout | 30s | TCP 讀取階段 | 服務端等待客戶端發送數據包的超時(僅 TCP) |
net_write_timeout | 60s | TCP 寫入階段 | 服務端發送數據包給客戶端的超時(僅 TCP) |
innodb_lock_wait_timeout | 50s (5.6+ 可動態調整) | InnoDB 行鎖等待 | 事務等待行鎖的最大時間,超時回滾當前語句 |
innodb_rollback_on_timeout | OFF | 事務級別 | ON 時超時回滾整個事務,OFF 僅回滾當前語句 |
slave_net_timeout | 3600s (1h) | 主從同步 | 從庫判斷主庫心跳超時,觸發重連 |
rpl_stop_slave_timeout | 31536000s | 主從停止 | STOP SLAVE 等待從線程退出的超時 |
lock_wait_timeout | 31536000s | MDL 鎖/表鎖 | 等待元數據鎖/表鎖的超時(5.6+) |
delayed_insert_timeout | 300s | INSERT DELAYED | MyISAM 延遲插入處理線程等待新語句的時間 |
innodb_flush_log_at_timeout | 1s | Redo Log 刷盤 | 日誌緩衝區刷盤間隔(與 sync_binlog 配合) |
wait_timeout vs interactive_timeout:最易踩坑的「8 小時定律」validationQuery 或 testOnBorrow,夜間低峰期連接空閒超過 8 小時會被 MySQL 主動斷開,晨間業務報「Communications link failure」。minEvictableIdleTimeMillis < wait_timeout(如 30 分鐘)、啟用 testWhileIdle=true、或縮短 wait_timeout(如 1 小時)配合心跳機制。interactive_timeout 只影響命令行工具,實則任何調用 mysql_real_connect(..., CLIENT_INTERACTIVE) 的客戶端均受影響。innodb_lock_wait_timeout:死鎖 vs 鎖等待的關鍵區別innodb_lock_wait_timeout 控制**,僅回滾 B 的**當前語句**(除非開啟 innodb_rollback_on_timeout=ON)。net_read_timeout / net_write_timeout:大數據傳輸的隱形殺手SELECT 大結果集、LOAD DATA 導入、Blob/Text 大字段讀寫,網絡抖動或客戶端處理緩慢導致超時斷開。slave_net_timeout:主從心跳檢測的靈敏度開關MASTER_CONNECT_RETRY=10、master-retry-count=86400 實現秒級故障感知。MASTER_HEARTBEAT_PERIOD(毫秒級心跳),更推薦使用 GTID + 半同步 + 心跳機制替代傳統超時檢測。connect_timeout:防禦「慢速攻擊」的第一道防線Lost connection to MySQL server at 'reading initial communication packet',可適當調大至 20-30s,但需同步檢查網絡延遲、防火牆、DNS 反解析(建議開啟 skip-name-resolve)。[mysqld]
# 連接層
max_connections = 2000
wait_timeout = 3600 # 1小時,配合連接池心跳
interactive_timeout = 3600
connect_timeout = 10
# 網絡傳輸層
net_read_timeout = 60
net_write_timeout = 60
# InnoDB 事務層
innodb_lock_wait_timeout = 30
innodb_rollback_on_timeout = ON # 避免部分提交導致數據不一致
# 主從同步層
slave_net_timeout = 60
rpl_stop_slave_timeout = 60
master_connect_retry = 10
master_retry_count = 86400
# 安全加固
skip-name-resolve
sql_mode = STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
超時參數看似簡單,實則牽一髮動全身。核心原則:
建立參數變更審計機制,每次調整必須經過壓測驗證,方能構建高可用、可觀測的 MySQL 服務體系。