日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

【SQLAlchemy】MySQL server has gone away 原因分析、解决方法

發(fā)布時(shí)間:2024/2/28 数据库 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【SQLAlchemy】MySQL server has gone away 原因分析、解决方法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

SQLAlchemy報(bào)錯(cuò):MySQL server has gone away

錯(cuò)誤日志

2020-01-03 20:00:00,072 - update_example_table.py - get_pcodes_arr_by_kind_from_db[line:147] - ERROR: (pymysql.err.OperationalError) (2006, “MySQL server has gone away (error(10053, ‘’))”)
[SQL: SELECT example_menu.p_codes AS example_menu_p_codes
FROM example_menu
WHERE example_menu.isactive = %(isactive_1)s AND example_menu.kind = %(kind_1)s]
[parameters: {u’kind_1’: ‘BLACK’, u’isactive_1’: 1}]
(Background on this error at: http://sqlalche.me/e/e3q8)

錯(cuò)誤原因

從字面理解,就是你連接的MySQL已經(jīng)走人了,不在了。相當(dāng)于你和另外一個(gè)人打電話,你一直沒有掛電話,但是你把電話放一邊了,直到你重新拎起電話想說點(diǎn)啥,才聽到里面『嘟,嘟,嘟,嘟…』的掛機(jī)聲,于是你就知道電話另一頭的人已經(jīng)gone away了。

線上碰到這個(gè)問題時(shí),通常就是拋一個(gè)異常,然后(主動(dòng)/被動(dòng))重新連接一下,你下次就重新執(zhí)行一下要執(zhí)行的語(yǔ)句就行。這就像你覺得有一番話非說不可,然后重新?lián)芰藗€(gè)電話過去。

什么情況下會(huì)gone away?就像剛才說的,當(dāng)你拿著一個(gè)電話太久,又不說話的時(shí)候,對(duì)面肯定就把你掛了;

當(dāng)sqlalchemy與MySQL建立了一個(gè)連接,而sqlalchemy又不對(duì)這個(gè)連接執(zhí)行任何(有含義)的語(yǔ)句,這個(gè)連接對(duì)于MySQL而言就處于sleep,當(dāng)sleep了太久,MySQL就把連接一頭關(guān)閉了(可能說了句"啥玩意兒")

這時(shí),如果sqlalchemy在這個(gè)連接上嘗試執(zhí)行語(yǔ)句,就會(huì)出現(xiàn)gone away的錯(cuò)誤。

conn.close() 是把連接放回連接池,不是真正的關(guān)閉;池子里的空閑連接在MySQL線程里sleep,長(zhǎng)時(shí)間不操作,MySQL把連接一端關(guān)閉了,所以第二天SQLAlchemy再用這個(gè)連接的時(shí)候,拋出MySQL server has gone away…

解決方法

1. 設(shè)置SQLAlchemy的連接有效期,在MySQL關(guān)閉它之前,我先關(guān)閉它

因?yàn)閟coped_session是threadlocal的,相同線程會(huì)用到相同的session,如果session還持有connection,從pool里checkout connection時(shí)不會(huì)進(jìn)行過期的檢查操作,直接使用,所以必須設(shè)置SQLAIchemy的有效期

SQLAlchemy連接池重新生成的周期默認(rèn)為timeout是2小時(shí),通過 SHOW VARIABLES 可以查看數(shù)據(jù)庫(kù)配置的timeout時(shí)間(如下圖所示),所以設(shè)置sqlalchemy的 "pool_recycle"參數(shù)小于360s,就會(huì)在數(shù)據(jù)庫(kù)服務(wù)器斷開連接之前,自己斷開并重新生成連接

2. 在Web框架的層面,每次請(qǐng)求處理完畢時(shí),顯式地關(guān)閉session。

a. web框架顯示關(guān)閉session的方法有很多,常規(guī)方法如下,在finally中主動(dòng)關(guān)閉seession
b. Django和Flask都有middleware機(jī)制,可以在接收請(qǐng)求之前和處理完請(qǐng)求之后對(duì)session進(jìn)行remove
c. Flask有一類修飾器hook,可以在請(qǐng)求后或請(qǐng)求前做一些事情,使用hook顯示關(guān)閉session如下

了解其他hook修飾器:

before_first_request:注冊(cè)一個(gè)函數(shù),在處理第一個(gè)請(qǐng)求之前運(yùn)行。 before_request:注冊(cè)一個(gè)函數(shù),在每次請(qǐng)求之前運(yùn)行。 after_request:注冊(cè)一個(gè)函數(shù),如果沒有未處理的異常拋出,在每次請(qǐng)求之后運(yùn)行。 teardown_request:注冊(cè)一個(gè)函數(shù),即使有未處理的異常拋出,也在每次請(qǐng)求之后運(yùn)行。 在使用session之前,先檢查其有效性,無效則創(chuàng)建新的session以供使用

3. 在使用session之前,先檢查其有效性,無效則創(chuàng)建新的session以供使用


拓展:類似問題 - Lost connection to mysql server during query

(使用的是Flask-SQLAlchemy)

一般由以下四種情況造成, 通過SHOW VARIABLES LIKE ‘’查看一下字段:

1、查詢中大量數(shù)據(jù)被發(fā)送,由于數(shù)據(jù)傳輸時(shí)間不夠導(dǎo)致,可以增加net_read_timeout的值。

net_read_timeout : mysql服務(wù)端從客戶端讀取(接收)數(shù)據(jù)時(shí),服務(wù)端等待客戶端響應(yīng)的超時(shí)時(shí)間,當(dāng)服務(wù)端正在從客戶端讀取數(shù)據(jù)時(shí),net_read_timeout控制何時(shí)超時(shí)

2、初次連接時(shí),連接時(shí)間設(shè)定太少,可以增加connect_timeout的值改善。

connect_timeout:在獲取連接階段(authenticate)起作用, 獲取MySQL連接是多次握手的結(jié)果,除了用戶名和密碼的匹配校驗(yàn)外,還有IP->HOST->DNS->IP驗(yàn)證,任何一步都可能因?yàn)榫W(wǎng)絡(luò)問題導(dǎo)致線程阻塞。為 了防止線程浪費(fèi)在不必要的校驗(yàn)等待上,超過connect_timeout的連接請(qǐng)求將會(huì)被拒絕。

3、有些少見的情況可以show global status like 'aborted_connets',這個(gè)全局變量在每一次服務(wù)器終止時(shí)會(huì)增加1,查看"reading authorization packet"獲取錯(cuò)誤信息。

4、BLOB值太大的問題,調(diào)整配置文件max_allowed_packet。

mysql根據(jù)配置文件會(huì)限制server接受的數(shù)據(jù)包大小。有時(shí)候大的插入和更新會(huì)被max_allowed_packet 參數(shù)限制掉,導(dǎo)致失敗。


拓展:【Python】SQLAlchemy:session何時(shí)commit,何時(shí)close?

Engine 相當(dāng)于一個(gè)創(chuàng)建連接的工廠,而不是連接本身。當(dāng)使用conn.close()時(shí),連接被放回到Engine的連接池當(dāng)中,而不是真正的關(guān)閉了。

如果想要在調(diào)用conn.close()時(shí),真正的關(guān)閉連接,可以使用poolclass=NullPool屬性:

from sqlalchemy.pool import NullPool db = create_engine('mysql://root@localhost/test_database', poolclass=NullPool)

拓展:初始問題 - 【Python】SQLAlchemy長(zhǎng)時(shí)間未請(qǐng)求,數(shù)據(jù)庫(kù)連接斷開的原因、解決方案

一個(gè)基于apscheduler的定時(shí)任務(wù),里面的任務(wù)使用了sqlalchemy,這個(gè)任務(wù)每天跑,但是第二天就連不上數(shù)據(jù)庫(kù)

總結(jié)

以上是生活随笔為你收集整理的【SQLAlchemy】MySQL server has gone away 原因分析、解决方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。