查询期间与MySQL服务器的连接丢失

Ota*_*vio 53 python 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)
#
Run Code Online (Sandbox Code Playgroud)

但我总是得到这个:

#
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
#
Run Code Online (Sandbox Code Playgroud)

你有什么主意吗?

Mar*_*rey 39

mysql文档有一整页专用于此错误:http: //dev.mysql.com/doc/refman/5.0/en/gone-away.html

值得注意的是

  • 如果向服务器发送不正确或太大的查询,也可能会出现这些错误.如果mysqld收到的数据包太大或无序,则会假定客户端出现问题并关闭连接.如果需要大查询(例如,如果使用大型BLOB列),则可以通过设置服务器的max_allowed_pa​​cket变量来增加查询限制,该变量的默认值为1MB.您可能还需要增加客户端的最大数据包大小.有关设置数据包大小的更多信息,请参见第B.5.2.10节"数据包太大".

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


imx*_*ylz 21

扩展mysql服务器的max_allowed_pa​​cket有三种方法:

  1. 更改mysql服务器计算机上的max_allowed_packet=64M文件/etc/mysql/my.cnf并重新启动服务器
  2. 在mysql服务器上执行sql: set global max_allowed_packet=67108864;
  3. Python连接到mysql后执行sql:

connection.execute('set max_allowed_pa​​cket = 67108864')


小智 12

确保在连接前关闭光标.我用这个解决了我的问题:

if cur and con:                        
    cur.close() 
    con.close() 
Run Code Online (Sandbox Code Playgroud)

  • 如果在连接之前关闭游标和连接,那么它不是一开始就无法连接吗? (2认同)

Mar*_*ers 9

您需要增加连接的超时.如果由于某种原因您不能或不想这样做,您可以尝试致电:

data = db.query(sql).store_result()
Run Code Online (Sandbox Code Playgroud)

这将立即获取所有结果,然后您的连接将不会超时迭代它们.


xvg*_*vga 8

您还可以在分叉子进程的应用程序中遇到此错误,所有这些应用程序都尝试使用与MySQL服务器相同的连接.通过为每个子进程使用单独的连接可以避免这种情况.

福克斯可能会打你.但请注意不要在这种情况下.

  • 是的,这对我来说是个问题。我使用 uwsgi 来服务我的 Flask 应用程序,在 uwsi 配置文件中,我将进程指令设置为 5。我将其更改为 1 并且它有效,但我不明白这个问题。每个进程不应该生成自己的连接吗? (2认同)

H6.*_*H6. 5

我是我的理由

错误2013(HY000):查询期间与MySQL服务器的连接丢失

错误是我的表的部分已损坏.我也无法进入mysqldump我的桌子,因为有些行打破了它.该错误与如上所述的任何存储器问题等无关.

好消息是,MySQL向我返回了行号,这是第一个失败的行号.它就像是

mysqldump:错误2013:在将行mytable转储到第12723行时,在查询期间丢失了与MySQL服务器的连接

解决方案是将数据复制到新表中.在我的情况下,我丢失了10行数据,因为我不得不跳过这些损坏的行.首先,我创建了一个"tmp"表,其中包含旧表的模式.SHOW CREATE TABLE是你的朋友.例如

SHOW CREATE TABLE mydatabase.mytable;
Run Code Online (Sandbox Code Playgroud)

随着我创建了新表.我们称之为mytabletmp.然后通过例如复制您能够复制的行

insert into mysqltabletmp select * from mytable where id < 12723;
insert into mysqltabletmp select * from mytable where id > 12733;
Run Code Online (Sandbox Code Playgroud)

在删除旧表之后,将tmp-table重命名为旧表名.

彼得有一些关于这个问题的好消息.