1. 错误内容:
在使用flask_sqlalchemy的时候,每当长时间未请求,当再一次使用连接的时候,就会报
pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query')
2. 报错原因:
我们一般使用数据库连接池来获取连接,连接池里的连接可能会较长时间不关闭,等待被使用,这就与mysql连接超时机制起冲突了,当连接池配置永不关闭或者关闭时间超过MySQL中设置的超时时间就会出现我所遇到的问题。
- 查看MySQL中的超时时间:
show variables like '%timeout%';
我们这里的wait_timeout设置的值为900,也就是15分钟,当超过15分钟没有新的数据库请求的时候,数据库连接就会断开,如果我们连接池的配置是用不关闭或者关闭时间超过15分钟,这个时候连接池没有回收并且还认为连接池与数据库之间的连接还存在,就会继续连接,但是数据库连接断开了,就会报错数据库连接失败!
3. flask_sqlalchemy的变量:
if sa_url.drivername.startswith('mysql'):
sa_url.query.setdefault('charset', 'utf8')
if sa_url.drivername != 'mysql+gaerdbms':
options.setdefault('pool_size', 10)
options.setdefault('pool_recycle', 7200)
- SQLALCHEMY_POOL_RECYCLE: 自动回收连接的秒数,这对 MySQL 是必须的,默认 情况下 MySQL 会自动移除闲置 8 小时或者以上的连接。 需要注意地是如果使用 MySQL 的话, Flask-SQLAlchemy 会自动地设置这个值为 2 小时。
4. 解决办法:
- 修改mysql配置文件里wait_timeout参数,让这个时间大于连接池的回收时间(修改配置文件需要重启数据库,不推荐!,另外调高wait_timeout也会造成很多的连接保持,使连接数过高,造成浪费)
- 修改数据库连接池的配置,我们这里是wait_timeout=900,这里可以设置成
app.config["SQLALCHEMY_POOL_RECYCLE"] = 800
,只要小于MySQL的超时连接时间即可
5. 更多参数配置:
http://www.pythondoc.com/flask-sqlalchemy/config.html