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)
#
但是我总是这样:
#
Traceback (most recent call last):
File "teste.py", line 124, in
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 > ignored
#
你有什么主意吗?
Otavio asked 2020-01-08T00:25:35Z
18个解决方案
39 votes
mysql文档有专门针对此错误的整个页面:[http://dev.mysql.com/doc/refman/5.0/en/gone-away.html]
值得注意的是
如果您向服务器发送不正确或太大的查询,您也会收到这些错误。 如果mysqld收到的数据包太大或顺序混乱,则认为客户端出了点问题,并关闭了连接。 如果需要大型查询(例如,如果使用大型BLOB列),则可以通过设置服务器的max_allowed_packet变量来增加查询限制,该变量的默认值为1MB。 您可能还需要增加客户端上的最大数据包大小。 有关设置数据包大小的更多信息,请参见第B.5.2.10节“数据包太大”。
通过使用--log-warnings = 2选项启动mysqld,可以获得有关丢失的连接的更多信息。 这会将一些断开连接的错误记录在hostname.err文件中
Mark Carey answered 2020-01-08T00:25:59Z
21 votes
有三种方法可以扩展mysql服务器的max_allowed_packet:
在mysql服务器计算机上更改文件/etc/mysql/my.cnf中的set global max_allowed_packet=67108864;并重新启动服务器
在mysql服务器上执行sql:set global max_allowed_packet=67108864;
连接到mysql后,Python执行sql:
connection.execute('设置max_allowed_packet = 67108864')
imxylz answered 2020-01-08T00:26:37Z
12 votes
连接前请确保关闭光标。 我已经解决了我的问题:
if cur and con:
cur.close()
con.close()
JiP answered 2020-01-08T00:26:57Z
8 votes
您需要增加连接超时。 如果由于某些原因您不能或不想这样做,可以尝试致电:
data = db.query(sql).store_result()
这将立即获取所有结果,因此您的连接不会在遍历所有结果的过程中超时。
Mark Byers answered 2020-01-08T00:27:22Z
8 votes
您还可能在派生子进程的应用程序中遇到此错误,所有应用程序都尝试使用与MySQL服务器的相同连接。 可以通过为每个子进程使用单独的连接来避免这种情况。
叉子可能会撞到您。 但是请注意不要在这种情况下。
xvga answered 2020-01-08T00:27:46Z
5 votes
我的情况是
错误2013(HY000):在查询过程中失去与MySQL服务器的连接
错误是我表的某些部分已损坏。 我也无法将mysqldump放在我的桌子上,因为有些行将其弄坏了。该错误与如上所述的任何内存问题无关。
令人高兴的是,MySQL向我返回了第一个失败的行号。 就像
mysqldump:错误2013:转储表mytable的行时,查询期间与MySQL服务器的连接丢失:12723
解决方案是将数据复制到新表中。 就我而言,我丢失了10行数据,因为我不得不跳过这些损坏的行。 首先,我用旧表的架构创建了一个“ tmp”表。 SHOW CREATE TABLE是您的朋友在这里。 例如。
SHOW CREATE TABLE mydatabase.mytable;
我创建了新表。 我们称之为mytabletmp。 然后复制您能够通过例如复制的行
insert into mysqltabletmp select * from mytable where id < 12723;
insert into mysqltabletmp select * from mytable where id > 12733;
在删除旧表之后,将tmp-table重命名为旧表名称。
Peter也提供了有关此问题的一些不错的信息。
H6. answered 2020-01-08T00:28:42Z
2 votes
将“ max_allowed_packet”设置设置为64M,然后重新启动MySql服务器。 如果那不能解决您的问题,则问题可能出在其他地方。
我有一个多线程PHP CLI应用程序,它可以同时进行查询,最近我注意到了这个问题。 现在对我来说很明显,MySql服务器将来自同一IP的所有连接视为“单个”连接,因此,只要一个查询完成,就删除所有连接。
我想知道是否有办法使MySql允许说来自同一IP的100个连接,并将每个连接视为一个单独的连接。
NiX answered 2020-01-08T00:29:12Z
1 votes
这是因为使用mariadb发生在我身上,因为我在unique key列中创建了varchar(255)列。由于插入正在超时,所以猜测对于一个唯一的来说太重了。
Amalgovinus answered 2020-01-08T00:29:32Z
1 votes
如果某人或某物使用KILL命令杀死了您的连接,也会发生这种情况。
Sam Brightman answered 2020-01-08T00:29:52Z
1 votes
当我尝试更新磁盘上的大小大于可用磁盘空间的表时,这发生在我身上。 对我来说,解决方案只是增加可用磁盘空间。
e18r answered 2020-01-08T00:30:12Z
1 votes
我也遇到过类似的问题。 在我的情况下,可以通过以下方式获取光标来解决:
cursor = self.conn.cursor(buffered=True)
user6938211 answered 2020-01-08T00:30:32Z
0 votes
就我而言,在采购将表放置在错误顺序中的SQL转储时遇到了这个问题。 有问题的CREATE包含一个CONSTRAINT ...引用,该引用引用了尚未创建的表。
我找到了有问题的表,并将其CREATE语句移到有问题的表的上方,错误消失了。
我遇到的与此错误的转储有关的另一个错误是错误1005 / errno:150-“无法创建表”,再次是表的创建顺序混乱。
user3975359 answered 2020-01-08T00:31:02Z
0 votes
当我的CONSTRAINT名称与其他CONSTRAINT名称具有相同的名称时,这发生在我身上。
更改我的CONSTRAINT名称可以解决此问题。
tama answered 2020-01-08T00:31:26Z
0 votes
多重处理和Django DB不能一起使用。
我最终在新过程中关闭了Django 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()调用一个以
其他建议使用
from multiprocessing.dummy import Pool as ThreadPool
它解决了我的问题(2013年,连接丢失),但是线程在执行IO时使用GIL,以便在IO完成时将其释放。
相比之下,Process产生了一组互相交流的工人,这可能会比较慢。
我建议您安排时间。另一个提示是使用由scikit-learn项目支持的joblib。一些性能结果表明它可以执行本机Pool()。尽管它有责任让编码器来验证真实的运行时成本。
CodeFarmer answered 2020-01-08T00:32:22Z
0 votes
我遇到了同样的问题。 由于其他一些问题,我试图将cnx.close()行添加到其他函数中。 相反,我删除了所有这些无关的关闭,并像这样设置我的课程:
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()
在此类中调用的任何函数都是连接,提交和关闭。
Mr Panda answered 2020-01-08T00:32:47Z
0 votes
当我尝试对数百万条记录进行批量插入时,出现“管道中断”错误。 我最终解决了这一问题,方法是将数据分成较小的批处理大小,然后针对需要执行的每个插入操作,使用mysql光标运行executemany命令。 这解决了问题,并且似乎没有以任何明显的方式影响性能。
例如。
def chunks(data):
for i in range(0, len(data), CHUNK_SIZE):
yield data[i:i + CHUNK_SIZE]
def bulk_import(update_list):
new_list = list(chunks(update_list))
for batch in new_list:
cursor.execute(#SQL STATEMENT HERE)
imapotatoe123 answered 2020-01-08T00:33:11Z
0 votes
与@imxylz相同,但是我必须使用mycursor.execute('set GLOBAL max_allowed_packet=67108864'),因为我得到一个只读错误,而没有使用GLOBAL参数。
mysql.connector.__version__
8.0.16
JLJ answered 2020-01-08T00:33:36Z
-1 votes
解决方法非常简单,请转到您的phpadmin的控制面板,然后单击config /,然后编辑您看到的.ini文件。 如果不是用于连接的端口,请查找端口3306,将3306更改为正在使用的端口。 在登录屏幕上,只需将localhost作为服务器名,如果您的端口不是默认端口,或者您未按原样在sql配置leavit中更改文件名my.ini,则将其放置。 然后输入您的用户名:root或您创建的用户名,然后输入密码:1234或您分配的用户名。 如果您正在连接本地,请不要检查url选项。 然后输入您要编辑的数据库的名称。 注意:连接后,您将看到服务器或要连接到的服务器上的数据库列表。
Tony calvo answered 2020-01-08T00:33:57Z