SQLAlchemy错误MySQL服务器已经消失

Pat*_*rns 13 python mysql sqlalchemy flask

错误OperationalError: (OperationalError) (2006, 'MySQL server has gone away')我在Flask上编码项目时已收到此错误,但我无法理解为什么我会收到此错误.

我有代码(是的,如果代码小,执行速度快,那么没有错误)就像这样\

db_engine = create_engine('mysql://root@127.0.0.1/mind?charset=utf8', pool_size=10, pool_recycle=7200)
Base.metadata.create_all(db_engine)

Session = sessionmaker(bind=db_engine, autoflush=True)
Session = scoped_session(Session)
session = Session()

# there many classes and functions

session.close()
Run Code Online (Sandbox Code Playgroud)

此代码返回错误'MySQL server has gone away',但一段时间后,当我在脚本中使用暂停时返回它.

我在openserver.ru中使用的Mysql(它就像wamp这样的web服务器).

谢谢..

Rom*_*man 18

查看 mysql 文档,我们可以看到出现此错误的原因有很多。但是,我看到的两个主要原因是:


1)最常见的原因是因为超过 8 小时没有使用(默认设置)而断开连接

默认情况下,如果没有发生任何事情,服务器会在八小时后关闭连接。你可以在启动mysqld时通过设置wait_timeout变量来改变时间限制

为了完整起见,我将提到两种处理方法,但其他答案中已经提到了它们:

A : 我有一份很长的工作,所以我的连接是陈旧的。为了解决这个问题,我刷新了我的连接:

create_engine(conn_str, pool_recycle=3600)  # recycle every hour
Run Code Online (Sandbox Code Playgroud)

B : 我有一个长时间运行的服务和长时间的不活动。为了解决这个问题,我在每次调用之前 ping mysql:

create_engine(conn_str, pool_pre_ping=True)
Run Code Online (Sandbox Code Playgroud)

2)我的数据包太大,应该会抛出这个错误:

_mysql_exceptions.OperationalError: (1153, "Got a packet bigger than 'max_allowed_packet' bytes")
Run Code Online (Sandbox Code Playgroud)

我只看到它隐藏在跟踪的中间,虽然通常你只会看到通用的_mysql_exceptions.OperationalError (2006, 'MySQL server has gone away'),所以很难捕捉到,特别是如果日志在多个地方。

上面的文档说最大数据包大小默认为 64MB,但实际上是 16MB,可以用SELECT @@max_allowed_packet

要解决此问题,请减小INSERT或UPDATE调用的数据包大小。


Mil*_*ric 15

SQLAlchemy现在有一篇很好的文章说明如何使用ping来对你的连接的新鲜度持悲观态度:

http://docs.sqlalchemy.org/en/latest/core/pooling.html#disconnect-handling-pessimistic

从那里,

from sqlalchemy import exc
from sqlalchemy import event
from sqlalchemy.pool import Pool

@event.listens_for(Pool, "checkout")
def ping_connection(dbapi_connection, connection_record, connection_proxy):
    cursor = dbapi_connection.cursor()
    try:
        cursor.execute("SELECT 1")
    except:
        # optional - dispose the whole pool
        # instead of invalidating one at a time
        # connection_proxy._pool.dispose()

        # raise DisconnectionError - pool will try
        # connecting again up to three times before raising.
        raise exc.DisconnectionError()
    cursor.close()
Run Code Online (Sandbox Code Playgroud)

并进行测试以确保上述工作:

from sqlalchemy import create_engine
e = create_engine("mysql://scott:tiger@localhost/test", echo_pool=True)
c1 = e.connect()
c2 = e.connect()
c3 = e.connect()
c1.close()
c2.close()
c3.close()

# pool size is now three.

print "Restart the server"
raw_input()

for i in xrange(10):
    c = e.connect()
    print c.execute("select 1").fetchall()
    c.close()
Run Code Online (Sandbox Code Playgroud)

  • 我真的不喜欢没有评论的人投票.所以应该真的要求对投票给予评论...... (6认同)