標籤:
之前遇到開發詢問“mysql server has gone away”的問題,想當然的就認為是由於太長時間沒有操作,導致超過MySQL服務端上的wait_timeout的設定,最終串連被MySQL服務端回收了。
最近一次突然自己同事寫的指令碼在運行過程中被中斷了,查看報錯資訊依然是“mysql server has gone away”,同事的指令碼在多個MySQL執行個體上根據時間範圍取值,雖然執行時間長了點,但是絕對不會有超過wati_timeout的空閑等待時間,於是去學習了一下到底有哪幾種情況會出現這個報錯。
情況1
就是最常見的,一個連結超過wait_timeout的設定時間沒有做任何事情,被MySQL服務端關閉連結並回收資源。
針對這種情況要不調大wait_timeout或者不斷的向MySQL服務端發送心跳訊號,保持連結。
情況2
你的連結被kill掉了,有可能是DBA人工操作,也可能是各種自動化系統操作,可以通過監控status中com_kill狀態值來判斷剛才是否發生了kill操作。
情況3
MySQL的用戶端如果預設配置中有mysql_opt_read_timeout或者mysql_opt_write_timeout參數,並且操作時間超過了其中一個參數的設定,用戶端自身會關閉連結。所以需要瞭解自己使用的mysql用戶端。
情況4
還有一種可能是發送的請求或者返回的結果集太大了,超過MySQL的max_allowed_packet_size的設定,導致發生這種報錯。多說一句,這個參數需要用戶端和服務端同時配置並保持一致才會生效。
最常見的Linux上的mysql用戶端可以使用如下命令查看:
mysql --help | grep ^max-allowmax-allowed-packet 1677721
我們可以看到我們伺服器上預設的設定為16M。
情況5
這種比較罕見的情況是MySQL服務端的DNS反解失敗導致,理論上我們可以配置–skip-networking參數來規避這種問題。(但是官方文檔居然說即使配置了也可能出現這種報錯,T_T)
情況6
還有就是如果程式使用了多進程,而所有進程都嘗試使用同一個連結和MySQL服務端建立連結的時候就會出現gone away的報錯了。(初步懷疑,這也就是我同事遇到的問題了。)
情況7
最後這種比較弱,但是真實發生過,那就是mysql執行個體宕機了。執行個體都沒有了,自然什麼都沒有了。當然這種情況判斷起來比較方便,一般都會有mysql的存活監控。但是要小心一種情況,就是執行個體crash後迅速recover,如果監控程式的間隔大於recover的時間,那麼就很難發現了。建議使用如下方法複查一下,另外針對uptime最好做為狀態的一個必要監控點。
show global status like ‘uptime‘;+---------------+---------+| Variable_name | Value |+---------------+---------+| Uptime | 1230699 |+---------------+---------+
最後如果想對“mysql server has gone away”進行詳細的追查,建議在mysqld執行個體啟動的時候添加–log-warnings=2 參數,這樣就可以在error日誌中看到詳細的資訊了。
mysql server has gone away的原因