others - 在查询过程中丢失MySQL服务器的连接

我有一个很大的表,我需要处理所有行。我总是得到连接丢失的消息,也无法重新连接,这是我的代码:


#
import MySQLdb

class DB:
 conn = None

 def connect(self):
 self.conn = MySQLdb.connect('hostname', 'user', '*****', 'some_table', cursorclass=MySQLdb.cursors.SSCursor)

 def query(self, sql):
 try:
 cursor = self.conn.cursor()
 cursor.execute(sql)
 except (AttributeError, MySQLdb.OperationalError):
 self.connect()
 cursor = self.conn.cursor()
 cursor.execute(sql)
 return cursor
#

#
db = DB()
sql = "SELECT bla FROM foo"
data = db.query(sql)

for row in data:
 do_something(row)
#

但我总是得到这样的结果:


#
Traceback (most recent call last):
 File "teste.py", line 124, in <module>
 run()
 File "teste.py", line 109, in run
 for row in data:
 File "/usr/lib64/python2.5/site-packages/MySQLdb/cursors.py", line 417, in next
 row = self.fetchone()
 File "/usr/lib64/python2.5/site-packages/MySQLdb/cursors.py", line 388, in fetchone
 r = self._fetch_row(1)
 File "/usr/lib64/python2.5/site-packages/MySQLdb/cursors.py", line 285, in _fetch_row
 return self._result.fetch_row(size, self._fetch_type)
 _mysql_exceptions.OperationalError: (2013, 'Lost connection to MySQL server during query')
 Exception _mysql_exceptions.OperationalError: (2013, 'Lost connection to MySQL server during query') in <bound method SSCursor.__del__ of <MySQLdb.cursors.SSCursor object at 0x7f7e3c8da410>> ignored
#

有什么办法吗?

时间:

mysql文档有一个专门针对此错误的页面: http://dev.mysql.com/doc/refman/5.0/en/gone-away.html

值得注意的是

  • 如果向服务器发送的查询不正确或太大,也会得到这些错误,如果mysqld收到的数据包太大或无序,它会假定客户端出现问题,并且关闭连接。如果需要大查询(例如,如果你正在处理大blob列),可以通过设置服务器变量的max_allowed_packet来增加查询限制,你还可能需要在客户端上增加最大包大小,有关设置数据包大小的更多信息,请参见第B.5.2.10节,"数据包太大"。

  • 你可以通过使用--log-warnings=2选项启动mysqld来获得关于丢失连接的更多信息。 这会记录hostname.err文件中的一些断开连接的错误

确保在连接前关闭游标,我已经解决了我的问题:


if cur and con: 
 cur.close() 
 con.close() 

你需要增加连接的超时时间,如果不能或不想这样做,可以尝试调用:


data = db.query(sql).store_result()

这将立即获取所有结果,然后你的连接不会超过迭代过程中超时。

在fork子进程的应用程序中,你也可以遇到这个错误,所有这些应用程序都试图使用与MySQL服务器相同的连接。 可以通过为每个子进程使用单独的连接来避免这一点。

叉子可能会打中你。小心不要在这种情况下。

将'max_allowed_packet'设置为64M,并且重新启动MySql服务器,如果没有解决问题,那么问题可能在其他地方。

有三种方法可以扩大mysql服务器的max_allowed_packet :

  1. 在mysql服务器机器上的文件/etc/mysql/my.cnf中更改max_allowed_packet=64M,然后重启服务器,
  2. 在mysql服务器上执行sql : set global max_allowed_packet=67108864;
  3. python在连接到mysql后执行sql :

connection.execute('set max_allowed_packet=67108864' )

我的情况是

ERROR 2013 (HY000) : Lost connection to MySQL server during query

错误是我的表的部分已损坏。

好消息是,MySQL给我的是失败的行号。它就像是

mysqldump : Error 2013 : Lost connection to MySQL server during query when dumping table mytable at row : 12723

解决方法是将数据复制到新表中,由于我必须跳过这些损坏的行,在我的例子中丢失了10行数据,首先我创建了一个"tmp表,其中包含旧的模式,例如


SHOW CREATE TABLE mydatabase.mytable;

我创建了新表格,


insert into mysqltabletmp select * from mytable where id < 12723;
insert into mysqltabletmp select * from mytable where id > 12733;

在删除旧表之后,将tmp表重命名为旧表名。

这是我和MariaDB发生的,因为我做了一个 varchar(255) 列。 我想这对于一个唯一的人来说太重了,因为插入是超时的。

如果使用KILL命令杀死连接,也可能发生这种情况。

...