查询期间失去与 MySQL 服务器的连接

Posted

技术标签:

【中文标题】查询期间失去与 MySQL 服务器的连接【英文标题】:Lost connection to MySQL server during query 【发布时间】:2010-12-25 11:39:49 【问题描述】:

我有一个巨大的表,我需要处理其中的所有行。我总是收到这个丢失的连接消息,我无法重新连接并将光标恢复到它的最后一个位置。这基本上是我在这里的代码:

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

你有什么想法吗?

【问题讨论】:

从 connect() 调用中删除“cursorclass=MySQLdb.cursors.SSCursor”就足够了。它现在工作得很好。谢谢。 我遇到了同样的问题,但是我有大约 1B 行数据,所以我想使用 SSCursor 在 mysqld 端而不是我的 python 应用程序上缓存查询的数据。将 net_write_timeout 扩大到 1 小时解决了这个问题 :) 致从 Google 来到这里的人们:如果您使用多线程,则需要为每个线程提供自己的连接。 【参考方案1】:

mysql 文档有一整页专门针对此错误: http://dev.mysql.com/doc/refman/5.0/en/gone-away.html

值得注意的是

如果您向服务器发送不正确或太大的查询,也可能会出现这些错误。如果 mysqld 收到一个太大或乱序的数据包,它会假设客户端出现问题并关闭连接。如果您需要大查询(例如,如果您使用大 BLOB 列),您可以通过设置服务器的 max_allowed_pa​​cket 变量来增加查询限制,该变量的默认值为 1MB。您可能还需要增加客户端的最大数据包大小。有关设置数据包大小的更多信息,请参见第 B.5.2.10 节“数据包太大”。

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

【讨论】:

另一个原因可能是mysqld崩溃了。【参考方案2】:

mysql服务器的max_allowed_pa​​cket有三种放大方式:

    在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')

【讨论】:

【参考方案3】:

对于派生子进程的应用程序,您也可能会遇到此错误,所有这些子进程都尝试使用与 MySQL 服务器的相同连接。这可以通过为每个子进程使用单独的连接来避免。

叉子可能会撞到你。不过在这种情况下请注意。

【讨论】:

是的,这对我来说是个问题。我正在使用 uwsgi 为我的烧瓶应用程序提供服务,并且在 uwsi 配置文件中,我将 processes 指令设置为 5。我将其更改为 1 并且它有效,但我不明白这个问题。每个进程不应该生成自己的连接吗? @Rockstar5645 这个问题是谁解决的? @vishal 我不记得了,但看起来我将进程指令从 5 更改为 1。【参考方案4】:

确保在连接前关闭光标。我已经解决了我的问题:

if cur and con:                        
    cur.close() 
    con.close() 

【讨论】:

如果在连接之前关闭游标和连接,是不是一开始就无法连接?【参考方案5】:

您需要增加连接的超时时间。如果由于某种原因您不能或不想这样做,您可以尝试致电:

data = db.query(sql).store_result()

这将立即获取所有结果,然后您的连接不会在遍历它们的中途超时。

【讨论】:

供参考和永久解决方案mysql docs 另请查看***【参考方案6】:

我的情况是什么原因

ERROR 2013 (HY000): 查询期间丢失与 MySQL 服务器的连接

错误是我的表的某些部分损坏了。我也无法mysqldump 我的表,因为有些行破坏了它。 该错误与上述任何内存问题等无关。

好消息是 MySQL 向我返回了第一个失败的行号。有点像

mysqldump:错误 2013:在查询期间在第 12723 行转储表 mytable 时丢失与 MySQL 服务器的连接

解决方案是将数据复制到新表中。就我而言,我丢失了 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 重命名为旧表名。

也有some nice Information from Peter关于这个问题。

【讨论】:

【参考方案7】:

这发生在我的 mariadb 上,因为我创建了一个 varchar(255) 列和一个 unique key.. 猜想这对于一个独特的来说太重了,因为插入超时。

【讨论】:

【参考方案8】:

多处理和 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,丢失连接)问题,但是线程使用 GIL,在做 IO 时,会在 IO 完成时释放它。

相比之下,Process 会产生一组相互通信的工作人员,这可能会更慢。

我建议你计时。 一个小技巧是使用由 scikit-learn 项目支持的joblib。 一些性能结果表明它执行了本机 Pool().. 尽管它让编码人员负责验证真正的运行时间成本。

【讨论】:

> 多处理和 Django DB 不能很好地配合使用。今天也是这样,真是令人沮丧。 (2013, 'Lost connection to MySQL server during query') (2006, "MySQL server has gone away (BrokenPipeError(32, 'Broken Pipe'))") (ಥ﹏ಥ)【参考方案9】:

将“max_allowed_pa​​cket”设置为 64M 并重新启动您的 MySql 服务器。如果这不能解决您的问题,则问题可能出在其他地方。

我有一个执行同时查询的多线程 php CLI 应用程序,我最近注意到了这个问题。现在对我来说很明显,MySql 服务器将来自同一 IP 的所有连接视为“单个”连接,因此只要单个查询完成,就会丢弃所有连接。

我想知道有没有办法让 MySql 允许来自同一个 IP 的 100 个连接,并将每个连接视为一个单独的连接。

【讨论】:

我不认为您关于“来自同一 IP 的所有连接都与 'sing'e' 连接”的说法是正确的。您可能会看到,因为 mysql 方法可能正在重用您的 PHP“线程”之间的持久连接。 "现在对我来说很明显,MySql 服务器将来自同一 IP 的所有连接视为“单个”连接" => 这当然是完全错误的,可以通过启动十并行 mysql 客户端进程在同一个机器上同时监控 mysql 连接 - 每个客户端当然都有自己的连接。【参考方案10】:

如果有人或某事使用KILL command 终止您的连接,也会发生这种情况。

【讨论】:

【参考方案11】:

当我尝试更新磁盘上的大小大于可用磁盘空间的表时,这发生在我身上。我的解决方案就是增加可用磁盘空间。

【讨论】:

【参考方案12】:

在我的例子中,我在采购 SQL 转储时遇到了这个问题,该转储将表格放置在错误的顺序。有问题的 CREATE 包含一个 CONSTRAINT ... REFERENCES,它引用了一个尚未创建的表。

我找到了有问题的表,并将其 CREATE 语句移到有问题的表上方,错误消失了。

我遇到的与此错误转储有关的另一个错误是 ERROR 1005/errno: 150 -- "Can't create table" ,这又是表创建乱序的问题。

【讨论】:

【参考方案13】:

我也遇到过类似的问题。就我而言,它是通过以这种方式获取光标来解决的:

cursor = self.conn.cursor(buffered=True)

【讨论】:

我使用的是 mysql.connector 而不是 MySQLdb【参考方案14】:

与@imxylz 相同,但我必须使用mycursor.execute('set GLOBAL max_allowed_packet=67108864'),因为在不使用 GLOBAL 参数的情况下出现只读错误。

mysql.connector.__version__ 

8.0.16

【讨论】:

【参考方案15】:

当我的 CONSTRAINT 名称与其他 CONSTRAINT 名称相同时,我发生了这种情况。

更改我的CONSTRAINT 名称解决了这个问题。

【讨论】:

【参考方案16】:

我遇到了同样的问题。由于其他一些问题,我曾尝试将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()

在此类中调用的任何函数都是连接、提交和关闭。

【讨论】:

【参考方案17】:

当我尝试对数百万条记录进行批量插入时,我遇到了“管道损坏”的错误。我最终解决了这个问题,将我的数据分块成更小的批量大小,然后为我需要做的每个插入运行一个带有 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)

【讨论】:

【参考方案18】:

你可以看到我对类似问题的回答:

https://***.com/a/69610550/16647254

使用锁来解决这个问题

lock.acquire()
mysqlhelper.getconn()
result_db_num = mysqlhelper.update(sql, [businessid, md5_id])
mysqlhelper.end()
mysqlhelper.dispose()
lock.release()

【讨论】:

【参考方案19】:

我在使用 mariadb sqlalchemypandas 时也遇到了同样的情况,就像上面的 @iamapotatoe 一样,我还创建了一个函数来将数据帧分解成块并将它们移植到 sql一点一点的数据库。 如果更改 mysql 配置选项中的 max_allowed_packet 对您不起作用,则可以使用此功能。

def load_large_df(table_name,df_to_load,batch_size,engine):
    df_to_load = df_to_load.dropna(how='all')
    with engine.connect() as conn:
        conn.execute(f"DROP TABLE IF EXISTS table_name")
        rows = df_to_load.shape[0]
        batch = int(rows/batch_size)
        

        strt = 0
        while strt < rows:
            df = df_to_load[strt:].head(batch)
            df.to_sql(table_name,con=conn,if_exists='append')
            strt += batch

【讨论】:

Pandas 已经提供了一个专用(和优化的)参数chunksize 来分块导入大型数据帧。【参考方案20】:

解决起来很简单,到你的phpadmin控制面板点击config/然后编辑你看到的.ini文件。查找端口 3306,如果这不是您用于连接的端口,请将 3306 更改为您正在使用的端口。在您的登录屏幕上,只需为您的服务器输入 localhost,如果它不是默认端口,或者您没有按原样更改 sql 配置 leavit 中的文件名 my.ini,则为您的端口。然后输入您的用户名:root 或您创建的用户名,然后输入密码:1234 或您分配的用户名。如果您正在本地连接,请不要检查 url 选项。然后键入要编辑的数据库的名称。注意:连接后,您将看到您的服务器或您要连接的服务器上的数据库列表。

【讨论】:

记得使用 % 赋予用户对你的表和数据库的通用访问权限 我不知道这个答案有什么关系。 OP 试图询问为什么他在执行查询时会失去连接。 这个答案是题外话。

以上是关于查询期间失去与 MySQL 服务器的连接的主要内容,如果未能解决你的问题,请参考以下文章

错误代码:2013。查询期间丢失与 MySQL 服务器的连接

查询期间丢失与 MySQL 服务器的连接 - Python、MySql

在查询异常期间丢失与 MySQL 服务器的连接

Django OperationalError(2013,“查询期间丢失与 MySQL 服务器的连接”)

2013, '在查询期间丢失与 MySQL 服务器的连接 - Pymysql Microsoft sql server management Studio

Django 1.3 的随机错误“在查询期间丢失与 MySQL 服务器的连接”[关闭]