python连接服务器失败_python-查询期间失去与MySQL服务器的连接

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值