查询时与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
#
你有什么想法吗?
23 个回答
17
你可能会在一些应用程序中遇到这个错误,这些应用程序会创建子进程,而这些子进程都试图使用同一个MySQL服务器的连接。为了避免这个问题,可以为每个子进程使用一个单独的连接。
小心,创建子进程可能会给你带来麻烦。不过在这种情况下不用担心。
38
有三种方法可以增大mysql服务器的max_allowed_packet:
- 在mysql服务器的机器上,找到文件
/etc/mysql/my.cnf
,把max_allowed_packet=64M
改成你想要的大小,然后重启服务器。 - 在mysql服务器上执行这个sql命令:
set global max_allowed_packet=67108864;
。 - 在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文件中。