pymysql.err.OperationalError: (2006, “MySQL server has gone away (BrokenPipe

目录

第一种情况:真的是连接数据库超时导致,比较常见

第二种情况:MySQL插入内容超过4M

在使用python+Django写项目时,需要用到定时任务apscheduler,但服务在长时间运行时,定时任务会报错 pymysql.err.OperationalError: (2006, “MySQL server has gone away (BrokenPipeError(32, ‘Broken pipe’))”)

如下图所示,此时,我们可以通过如下方法解决,一共有三个地方。

pymysql.err.OperationalError: (2006, “MySQL server has gone away (BrokenPipe

图一

这个报错出现的原因:操作MySQL数据库的时候,连接超时或者连接的session已经被MySQL抛弃,因为使用了定时任务apscheduler,方式是持久层的框架sqlalchemy,所以,通过3方面来解决。

pymysql.err.OperationalError: (2006, “MySQL server has gone away (BrokenPipe

图二

第一、MySQL,MySQL默认的wait_timeout时间28800秒,即8小时,超过8小时,MySQL就会放弃连接。可以看一下自己的MySQL设置的时间是多少,运行show variables like ‘%timeout%’;这个SQL即可查看到,时间根据自己业务而定,我在这里就保持8小时不变。

pymysql.err.OperationalError: (2006, “MySQL server has gone away (BrokenPipe

图三

第二、需要修改apscheduler持久层连接时间,设置时间小于8小时,即,还没有到MySQL放弃session的时间,apscheduler就主动回收了连接,这样在使用的时候,可以解决由于超时,MySQL主动抛弃session导致的MySQL server has gone away错误。如下图所示,设置连接时间为7小时。并且pool_pre_ping为True,即每次从连接池中取连接的时候,都会验证一下与数据库是否连接正常,如果没有连接,那么该连接会被回收。

pymysql.err.OperationalError: (2006, “MySQL server has gone away (BrokenPipe

图四

第三、在Django中操作数据库时,有两种情况,一种是使用Django的ORM方式操作数据库,即Model.objects.filter()这种方式,我们在报错之前,即操作数据库之前,先关闭连接,再重连数据库,即可解决这种方式的报错情况,引入

from django.db import close_old_connections

在操作数据库之前,加上close_old_connections(),如下图所示。

pymysql.err.OperationalError: (2006, “MySQL server has gone away (BrokenPipe

图五

第四、另外一种方式是自定义执行SQL,原理一样,只需要在操作数据库前,关闭连接即可,引入

from django.db import connection

在操作数据库前,加上connection.close(),如下图所示。

pymysql.err.OperationalError: (2006, “MySQL server has gone away (BrokenPipe

图六

至此,通过上面的修改:

1、MySQL超时时间设置;

2、定时任务持久层设置

3、Django的ORM形式与自定义SQL两种方式操作前关闭连接;

就彻底解决了MySQL server has gone away这个报错。

第二种情况:MySQL插入内容超过4M

Bug描述:

用Python的pymysql向MySQL数据库insert插入数据时,遇到报错信息:(2006, “MySQL server has gone away (BrokenPipeError(32, ‘Broken pipe’))”),原因是插入的数据超过了4M,超过了MySQL默认的max_allowed_packet(默认值是4M),无法将数据插入到MySQL中.

这个报错是Redhat上的报错,如果在Windows上报错:Got a packet bigger than ‘max_allowed_packet’ bytes,与上面的原因一样.(其实直接连接MySQL,插入的数据超过4M也会遇到这个问题)

解决方法: 修改MySQL的max_allowed_packet值

1.通过命令修改

在终端登录mysql.

输入命令:show VARIABLES like ‘%max_allowed_packet%’;查看当前的max_allowed_packet值是多少.

命令:set global max_allowed_packet = 1024102432;设置新的max_allowed_packet值,如:设为32M,1M是1024*1024,自己需要多少M就自己设置.没有特别要求可以尽量设为2的幂,总之够用就行.

show VARIABLES like ‘%max_allowed_packet%’;
set global max_allowed_packet = 1024102432;
2.修改MySQL配置文件

Linux(Redhat/CentOS/Ubuntu)系统的配置文件是/etc/my.cnf,vim打开my.cnf,然后找到max_allowed_packet,修改成自己需要的值,如修改成32M,如果没有找到max_allowed_packet,则在[mysqld]下面增加一行max_allowed_packet = 32M即可.

max_allowed_packet = 32M
有些系统的mysql配置是自己设置过的,存放的位置可能不一样,配置文件名也可能不一样,甚至可能[mysql]和[mysqld]的配置写在不同文件中,这种情况需要自己找到[mysqld]所在的配置文件,然后在下面修改或新增.

Windows系统的MySQL配置文件是在MySQL安装目录下的my.ini(如果找不到,直接打开我的电脑,在搜索框中搜索).

找到my.ini后用记事本打开,找到max_allowed_packet,将值修改成自己需要的值,如:改成32M.

max_allowed_packet = 32M
如果找不到max_allowed_packet,先Ctrl + F搜一下,如果还是没有找到,则找到[mysqld],在[mysqld]下面增加一行max_allowed_packet = 32M.

3.一般来说,一条数据超过4M,都是很长的json字符串,如果这个json字符串可以分成多条数据,也可以将数据拆分成多条数据,然后批量插入MySQL中(具体实现方法自己找一下).

可以使用bytes()将字符串转成字节,然后看字符串大小是否超过了102410244

test_str = ‘[{“key”:”value”, “”: “”},{“key”:”value”, “”: “”},{“key”:”value”, “”: “”}]’

test_byte = bytes(test_str.encode(‘utf-8’))
print(len(test_byte))
print(len(test_byte) > 102410244)

Original: https://blog.csdn.net/u010033674/article/details/114916324
Author: 独孤清扬玩DB
Title: pymysql.err.OperationalError: (2006, “MySQL server has gone away (BrokenPipe

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/737496/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球