2018-10-01

MySQL server has gone away 解法,無廢話


MySQL gone away 就是 MySQL 斷線了,最大的原因在於操作時間大於設定。記住,是「操作」時才應該有這種事發生,不應該出現在你的 "run time" application。例你需要批次匯入大量動態更新資料。

你可以在 mysql (or phpmyadmin) 執行以下命令查看你的 timeout 設定
show global variables like '%timeout%'





Variable_nameValue
connect_timeout60
delayed_insert_timeout300
innodb_flush_log_at_timeout1
innodb_lock_wait_timeout50
innodb_rollback_on_timeoutOFF
interactive_timeout60
lock_wait_timeout31536000
net_read_timeout30
net_write_timeout60
rpl_stop_slave_timeout31536000
slave_net_timeout3600
wait_timeout60

這裡我們發現 interactive_timeout, wait_timeout 都只有 60秒,也就是說60秒內都沒動作將會導致連線中斷

解決方法有
1. 直接修改my.cnf文件
2. my sql 在建立連線時傳入參數修改 interactive_timeout, wait_timeout
3. 只在某個連線,某個動作時直接改變 interactive_timeout, wait_timeout

第1種方式將會導致整個 mysql 都會延長連線時間,你可能有很多 database,有不同應用。這種設定在用戶端一多時(例如website)就會導致無法建立新連線的問題

第2種方式則是在某個應用啟動連接 mysql 時修改 timeout, 並第1種會少很多無法連線問題

第3種方式則是只在執行你知道的某個已知需要較長久功能時才修改interactive_timeout, wait_timeout。這個方式是最有效率的,不會影響其它功能。因為你修改的 timeout 只在該 child process 有效,每次重新 fork 一個新 process 都是重載的預設參數。而且你一定知道哪些功能會需要較長時間連線,若你不知道,那表示問題大了,且問題在你身上。

修改 timeout 指令如下:
set interactive_timeout=900
set wait_timeout=900

php 例子:

$sql = "set interactive_timeout=900; set wait_timeout=900";
$GLOBALS['db']->query($sql);
....
需要等長時間的程序