问题
SQLAlchemy (0.9.8) and mysql-5.6.21-osx10.8-x86_64 and MAC OS X 10.3.3 (Yosemite)
I keep getting intermittent:
InterfaceError: (InterfaceError) 2013: Lost connection to MySQL server during query u'SELECT..... '
I have read up a few thread and most cases are resolved by adding this to my.cnf
max_allowed_packet = 1024M
which should be more than big enough for what I tried to do. After doing this, I step hit it intermittently. And putting this line in /etc/my.cnf:
log-error = "/Users/<myname>/tmp/mysql.err.log"
log-warnings = 3
I am hoping to get more details, but all I see is something like this:
[Warning] Aborted connection 444 to db: 'dbname' user: 'root' host: 'localhost' (Got an error reading communication packets)
I have reached a point where i think more detail better logging may help, or if there's something else i could try before this.
Thanks.
回答1:
looks like your MySQL connection is timing out after a long period of inactivity, I bet it won't happen if you're constantly querying your DB with existing settings. There are couple of settings on both MySQL and sql sides which should resolve this issue:
check your SQLa engine's
pool_recycle
value, try different / smaller value, e.g. 1800 (secs). If you're reading DB settings from file, set it aspool_recycle: 1800
otherwise specify it during engine init, e.g.
from sqlalchemy import create_engine
e = create_engine("mysql://user:pass@localhost/db", pool_recycle=1800)
check / modify your
wait_timeout
MySQL variable, see https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_wait_timeout which is the number of seconds the server waits for activity on a noninteractive connection before closing it. e.g.show global variables like 'wait_timeout';
find a combination that works for your environment.
回答2:
Based on suggestions from this, this and many other articles on the internet, wrapping all my functions with the following decorator helped me resolve the "Lost Connection" issue with mariadb as the backend db. Please note that db
below is an instance of flask_sqlalchemy.SQLAlchemy
, but the concept will remain the same for an sqlalchemy session too.
def manage_session(f):
def inner(*args, **kwargs):
# MANUAL PRE PING
try:
db.session.execute("SELECT 1;")
db.session.commit()
except:
db.session.rollback()
finally:
db.session.close()
# SESSION COMMIT, ROLLBACK, CLOSE
try:
res = f(*args, **kwargs)
db.session.commit()
return res
except Exception as e:
db.session.rollback()
raise e
# OR return traceback.format_exc()
finally:
db.session.close()
return inner
I also added pool_recycle of 50 seconds in Flask SQLAlchemy config, but that didnt visibly contribute to the solution.
EDIT1:
Below is a sample snippet of how it was used in the final code:
from flask_restful import Resource
class DataAPI(Resource):
@manage_session
def get(self):
# Get data rows from DB
来源:https://stackoverflow.com/questions/29755228/sqlalchemy-mysql-lost-connection-to-mysql-server-during-query