在使用flask_sqlalchemy的時候,每當長時間未請求(5分鍾,為啥時5分鍾,往下看),當再一次使用連接的時候,就會報
python pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query')
2013 Lost connection to MySQL server during query
原因:
項目配置:flask_sqlalchemy自動回收連接的秒數,這里我設置的是-1,也就是永遠不超時
SQLALCHEMY_POOL_RECYCLE =-1
而MySQL的wait_timeout默認是28800,也就是超過8小時的連接就會自動失效,而我要連接的mysql通過查看發現是300秒,
show variables like '%timeout%'
wait_timeout=300
真正的問題是:我們做項目一般使用數據庫連接池來獲取連接,連接池里的連接可能會較長時間不關閉,等待被使用,這就與mysql連接超時機制起沖突了,當連接池配置永不關閉或者關閉時間超過8小時就會出現我所遇到的問題。
當超過8個小時沒有新的數據庫請求的時候,數據庫連接就會斷開,如果我們連接池的配置是用不關閉或者關閉時間超過8小時,這個時候連接池沒有回收並且還認為連接池與數據庫之間的連接還存在,就會繼續連接,但是數據庫連接斷開了,就會報錯數據庫連接失敗!
解決辦法:
修改mysql配置文件里wait_timeout參數,讓這個時間大於連接池的回收時間(修改配置文件需要重啟數據庫,不推薦!)
修改數據庫連接池的配置,數據庫連接池都會帶有一個參數:回收時間(就是一定時間內不使用就會回收),修改這個參數的值,不要大於wait_timeout的值即可。在flask-SQLAlchemy中有個配置是SQLALCHEMY_POOL_RECYCLE(多之后對線程池中的線程進行一次連接的回收),如果這個值是-1代表永不回收,Flask-SQLALchemy 自動設定這個值為2小時,我們可以將這個值設置的小於wait_timeout參數的值也就是8小時即可。
禁用SQLAlchemy提供的數據庫連接池
只需要在調用 create_engine 是指定連接池為 NullPool,SQLAlchemy就會在執行 session.close() 后立刻斷開數據庫連接。當然,如果 session 對象被析構但是沒有被調用 session.close(),則數據庫連接不會被斷開,直到程序終止。
參考:http://www.pythondoc.com/flask-sqlalchemy/config.html
https://blog.csdn.net/sinat_42483341/java/article/details/103723691