| 變數 | 預設 | 範圍 | 說明 |
|---|---|---|---|
connect_timeout | 10 秒 | 握手階段 | 等待 Client 送連線封包,防惡意佔用連線槽 |
wait_timeout | 28800 (8h) | Non-interactive (JDBC/連線池) | 閒置超過此秒數自動斷開,**連線池必須設 maxLifetime < wait_timeout** |
interactive_timeout | 28800 (8h) | Interactive (mysql CLI) | CLI 閒置斷開時間 |
net_read_timeout | 30 秒 | TCP 讀取 | Server 等待 Client 傳資料 |
net_write_timeout | 60 秒 | TCP 寫入 | Server 向 Client 傳資料 |
long_query_time | 10 秒 | 慢查詢判定 | 超過此時間記入 Slow Log |
innodb_lock_wait_timeout | 50 秒 | 行鎖等待 | 事務等待鎖超時回滾 |
lock_wait_timeout | 31536000 (1年) | MDL/表鎖 | 極大值實際近乎不超時 |
mysql_real_connect(..., CLIENT_INTERACTIVE),如 mysql CLI、MySQL Workbench啟動時 Session 變數依客戶端類型從對應 Global 變數初始化。
-- 設定互動逾時 1 秒
SET SESSION interactive_timeout = 1;
-- 等待 2 秒再執行查詢 → ERROR 2006 (HY000): MySQL server has gone away
-- 設定非互動逾時 1 秒
SET SESSION wait_timeout = 1;
-- 連線池閒置 2 秒 → 同樣斷開
Statement stmt = conn.createStatement();
stmt.setQueryTimeout(60); // 秒
ResultSet rs = stmt.executeQuery("SELECT SLEEP(100);"); // 會在 60 秒拋 SQLException
原理:客戶端啟動 Timer 任務,超時呼叫 stmt.cancel(),**Server 端無感知**。
坑點:設太短 (如 10 秒) 導致正常長查詢被誤殺,建議 ≥ 60 秒或依 P99 調整。
OceanBase 支援 **Server 端 Query Timeout**,可中斷單一查詢而**不斷開 Session**,優於 MySQL 客戶端取消機制。
[mysqld]
# 連線池閒置 10 分鐘自動回收
wait_timeout = 600
interactive_timeout = 600
# 網路讀寫 30/60 秒足夠
net_read_timeout = 30
net_write_timeout = 60
# 慢查詢 1 秒
long_query_time = 1
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
# InnoDB 鎖等待 10 秒快速失敗
innodb_lock_wait_timeout = 10
掌握 wait_timeout (連線池生命週期)、net_read/write_timeout (網路異常)、innodb_lock_wait_timeout (鎖競爭)、JDBC setQueryTimeout (客戶端兜底) 四大維度,即可構建健壯的資料庫連線與查詢超時防護體系。