flask_sqlalchemy 2013 Lost connection to MySQL server during query
在使用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