MySQL server has gone away解決方法
一、(2006, 'MySQL server has gone away')
-
錯誤原因
從字面理解,就是你連線的MySQL已經走人了,不在了。相當於你和另外一個人打電話,你一直沒有掛電話,但是你把電話放一邊了,直到你重新拎起電話想說點啥,才聽到裡面『嘟,嘟,嘟,嘟...』的掛機聲,於是你就知道電話另一頭的人已經gone away了。
線上碰到這個問題時,通常就是拋一個異常,然後(主動/被動)重新連線一下,你下次就重新執行一下要執行的語句就行。這就像你覺得有一番話非說不可,然後重新撥了個電話過去。
什麼情況下會gone away?就像剛才說的,當你拿著一個電話太久,又不說話的時候,對面肯定就把你掛了;當sqlalchemy與MySQL建立了一個連線,而sqlalchemy又不對這個連線執行任何(有含義)的語句,這個連線對於MySQL而言就處於sleep,當sleep了太久,MySQL就把連線一頭關閉了(可能說了句"啥玩意兒"),這時,如果sqlalchemy在這個連線上嘗試執行語句,就會出現gone away的錯誤。
-
解決方法
- 設定SQLAlchemy的連線有效期,在MySQL關閉它之前,我先關閉它
因為scoped_session是threadlocal的,相同執行緒會用到相同的session,如果session還持有connection,從pool裡checkout connection時不會進行過期的檢查操作,直接使用,所以必須設定SQLAIchemy的有效期
SQLAlchemy連線池重新生成的週期預設為timeout是2小時,通過 SHOW VARIABLES 可以檢視資料庫配置的timeout時間(如下圖所示),所以設定sqlalchemy的 "pool_recycle"引數小於360s,就會在資料庫伺服器斷開連線之前,自己斷開並重新生成連線,
-
在Web框架的層面,每次請求處理完畢時,顯式地關閉session。
a. web框架顯示關閉session的方法有很多,常規方法如下,在finally中主動關閉seession b. Django和Flask都有middleware機制,可以在接收請求之前和處理完請求之後對session進行remove c. Flask有一類修飾器hook,可以在請求後或請求前做一些事情,使用hook顯示關閉session如下
瞭解其他hook修飾器戳:
- before_first_request:註冊一個函式,在處理第一個請求之前執行。
- before_request:註冊一個函式,在每次請求之前執行。
- after_request:註冊一個函式,如果沒有未處理的異常丟擲,在每次請求之後執行。
- teardown_request:註冊一個函式,即使有未處理的異常丟擲,也在每次請求之後執行。
- 在使用session之前,先檢查其有效性,無效則建立新的session以供使用
二、(2013 lost connection to mysql server during query)
一般由以下四種情況造成,通過SHOW VARIABLES LIKE ‘’檢視一下欄位:
1、查詢中大量資料被髮送,由於資料傳輸時間不夠導致,可以增加net_read_timeout的值。
net_read_timeout : mysql服務端從客戶端讀取(接收)資料時,服務端等待客戶端響應的超時時間,當服務端正在從客戶端讀取資料時,net_read_timeout控制何時超時
2、初次連線時,連線時間設定太少,可以增加connect_timeout的值改善。
connect_timeout:在獲取連線階段(authenticate)起作用, 獲取MySQL連線是多次握手的結果,除了使用者名稱和密碼的匹配校驗外,還有IP->HOST->DNS->IP驗證,任何一步都可能因為網路問題導致執行緒阻塞。為 了防止執行緒浪費在不必要的校驗等待上,超過connect_timeout的連線請求將會被拒絕。
3、有些少見的情況可以show global status like 'aborted_connets',這個全域性變數在每一次伺服器終止時會增加1,檢視"reading authorization packet"獲取錯誤資訊。
4、BLOB值太大的問題,調整配置檔案max_allowed_packet。
mysql根據配置檔案會限制server接受的資料包大小。有時候大的插入和更新會被max_allowed_packet 引數限制掉,導致失敗。
三、keyError(dict的key值不存在)
四、TypeError(方法接收的型別不符)
- 錯誤原因 對無效型別的操作,即你操作的這個型別可能為空或者不符合接收函式引數的型別,就無法執行
- 解決方法 如下面使用float函式使用異常捕捉避免TypeError
五、AttributeError('NoneType' object has no attribute 'get’ )
這種錯誤一般是由於呼叫物件為空,或者此物件沒有對應的attribute