在查询期间与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接收到一个太大或者不合理的数据包,就认为客户端出了问题,并closures连接。 如果您需要大的查询(例如,如果您使用的是较大的BLOB列),则可以通过设置服务器的max_allowed_packetvariables(默认值为1MB)来增加查询限制。 您可能还需要增加客户端上的最大数据包大小。 有关设置数据包大小的更多信息在第B.5.2.10节“数据包太大”中给出。
-
通过使用–log-warnings = 2选项启动mysqld,可以获得有关丢失连接的更多信息。 这会logginghostname.err文件中的一些已断开连接的错误
有三种方法可以放大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')
确保在连接之前closures光标。 我已经解决了我的问题:
if cur and con: cur.close() con.close()
您需要增加连接的超时时间。 如果因为某种原因你不能或不想这样做,你可以尝试拨打电话:
data = db.query(sql).store_result()
这将立即获取所有的结果,那么你的连接将不会中途迭代。
您也可以在forksubprocess的应用程序中遇到这个错误,所有这些错误都尝试使用与MySQL服务器相同的连接。 这可以通过为每个subprocess使用单独的连接来避免。
叉子可能会打你。 不要在这种情况下,但是。
我的情况是这个原因
错误2013(HY000):在查询期间与MySQL服务器失去连接
错误是我的表部分被损坏 。 我也无法mysqldump
我的表,因为一些行破坏它。 这个错误与上面提到的任何内存问题无关。
好的是,MySQL给我返回了第一个失败的行号。 这是类似的东西
mysqldump:错误2013:丢失连接到MySQL服务器在查询时转储表mytable在行:12723
解决方法是将数据复制到一个新表中。 在我的情况下,我失去了10行数据,因为我不得不跳过这些损坏的行。 首先,我创build了一个“tmp”表格,其中包含旧的表格。 SHOW CREATE TABLE
是你的朋友。 例如
SHOW CREATE TABLE mydatabase.mytable;
随着我创build了新的表格。 我们称之为mytabletmp 。 然后复制你可以通过例如复制的行
insert into mysqltabletmp select * from mytable where id < 12723; insert into mysqltabletmp select * from mytable where id > 12733;
之后,删除旧表,将tmp-table重命名为旧表名。
彼得也有一些关于这个问题的很好的信息 。
将“max_allowed_packet”设置为64M,然后重新启动MySql服务器。 如果这不能解决你的问题,问题可能在别处。
我有一个multithreading的PHP CLI应用程序,同时进行查询,我最近注意到这个问题。 现在很明显,MySql服务器将来自同一个IP的所有连接视为“单一”连接,因此,只要一个查询完成,就会丢弃所有连接。
我想知道是否有办法让MySql允许来自同一个IP的100个连接,并将每个连接视为单独的连接。
这是发生在我用mariadb,因为我做了一个varchar(255)
列一个unique key
..猜是太重了一个独特的,因为插入超时。
如果某人或某事使用KILL命令杀死了您的连接,也会发生这种情况。
当我尝试更新磁盘上的大小大于可用磁盘空间的表时,发生了这种情况。 对我来说,解决scheme只是增加可用的磁盘空间。
我也遇到类似的问题。 在我的情况下,通过以这种方式获得游标来解决这个问题:
cursor = self.conn.cursor(buffered=True)
在我的情况下,我遇到了这个问题,当发现一个SQL转储已经把表错误的顺序。 有问题的CREATE包含引用尚未创build的表的CONSTRAINT … REFERENCES。
我find了问题表,并将其CREATE语句移到违规表之上,并且错误消失了。
我遇到的另一个有关这个错误的转储错误是错误1005 /错误:150 – “无法创build表”,再次表的问题创build乱序。
当我的CONSTRAINT
名称与其他CONSTRAINT
名称具有相同的名称时,发生这种情况。
改变我的CONSTRAINT
名字解决了这个问题。
多处理和Django DB不能很好的一起玩。
我结束了在新的过程中closuresDjango DB连接的第一件事。
所以那个不会引用父级使用的连接。
from multiprocessing import Pool multi_core_arg = [[1,2,3], [4,5,6], [7,8,9]] n_cpu = 4 pool = Pool(n_cpu) pool.map(_etl_, multi_core_arg) pool.close() pool.join() def _etl_(x): from django.db import connection connection.close() print(x)
要么
Process.start()
调用一个以开始的函数
其他一些build议使用
from multiprocessing.dummy import Pool as ThreadPool
它解决了我的(2013,丢失连接)问题,但线程使用GIL,当做IO时,在IO完成时释放它。
相比之下,stream程产生了一组互相沟通的工作人员,可能会比较慢。
我build议你花时间。 小技巧是使用scikit-learn项目支持的joblib 。 一些性能结果表明它执行本地池()..虽然它把责任编码器来validation真正的运行时间成本。
我遇到了同样的问题。 由于其他一些问题,我曾尝试将cnx.close()
行添加到其他函数中。 相反,我删除了所有这些多余的closures,并像这样设置我的类:
class DBase: config = { 'user': 'root', 'password': '', 'host': '127.0.0.1', 'database': 'bio', 'raise_on_warnings': True, 'use_pure': False, } def __init__(self): import mysql.connector self.cnx = mysql.connector.connect(**self.config) self.cur = self.cnx.cursor(buffered=True) print(self.cnx) def __enter__(self): return DBase() def __exit__(self, exc_type, exc_val, exc_tb): self.cnx.commit() if self.cnx: self.cnx.close()
在这个类中调用的任何函数都是连接,提交和closures。