查询时与MySQL服务器失去连接

78 投票
23 回答
254797 浏览
提问于 2025-04-15 16:54

我有一个很大的表格,需要处理里面的所有行。但是我总是收到“连接丢失”的消息,无法重新连接,也无法把光标恢复到之前的位置。这是我现在的代码:

#
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
#

你有什么想法吗?

23 个回答

17

你可能会在一些应用程序中遇到这个错误,这些应用程序会创建子进程,而这些子进程都试图使用同一个MySQL服务器的连接。为了避免这个问题,可以为每个子进程使用一个单独的连接。

小心,创建子进程可能会给你带来麻烦。不过在这种情况下不用担心。

38

有三种方法可以增大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')
51

MySQL的文档中有一整页专门讲这个错误:

值得注意的是:

  • 如果你发送给服务器的查询有问题或者太大,也可能会出现这些错误。如果mysqld接收到一个包太大或者顺序不对,它会认为客户端出了问题,然后关闭连接。如果你需要发送很大的查询(比如处理大文件数据时),可以通过设置服务器的max_allowed_packet变量来增加查询的限制,默认值是1MB。你可能还需要在客户端那边增加最大包大小。关于如何设置包大小的更多信息,可以查看文档的B.5.2.10节,“包太大”。

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

撰写回答