GVKun编程网logo

MySQL server has gone away错误的解决办法(mysql server has gone away什么意思)

1

本文将为您提供关于MySQLserverhasgoneaway错误的解决办法的详细介绍,我们还将为您解释mysqlserverhasgoneaway什么意思的相关知识,同时,我们还将为您提供关于200

本文将为您提供关于MySQL server has gone away错误的解决办法的详细介绍,我们还将为您解释mysql server has gone away什么意思的相关知识,同时,我们还将为您提供关于2006 MySQL server has gone away & Got a packet、Django (2006, ''MySQL server has gone away'') 本地重现与解决、ERROR 2006 (HY000): MySQL server has gone away No、MySQL Backup--Xtrabackup备份异常(MySQL Server has gone away)的实用信息。

本文目录一览:

MySQL server has gone away错误的解决办法(mysql server has gone away什么意思)

MySQL server has gone away错误的解决办法(mysql server has gone away什么意思)

在我们使用mysql导入大文件sql时可能会报MySQL server has gone away错误,该问题是max_allowed_packet配置的默认值设置太小,只需要相应调大该项的值之后再次导入便能成功。该项的作用是限制mysql服务端接收到的包的大小,因此如果导入的文件过大则可能会超过该项设置的值从而导致导入不成功!下面我们来看一下如何查看以及设置该项的值。

查看 max_allowed_packet 的值

show global variables like ''max_allowed_packet'';
+--------------------+---------+
| Variable_name      | Value   |
+--------------------+---------+
| max_allowed_packet | 4194304 |
+--------------------+---------+

可以看到默认情况下该项的大小只有4M,接下来将该值设置成150M(1024*1024*150)

set global max_allowed_packet=157286400;

此时再查看大小

show global variables like ''max_allowed_packet'';

通过调大该值,一般来说再次导入数据量大的sql应该就能成功了,如果任然报错,则继续再调大一些就行,请注意通过在命令行中进行设置只对当前有效,重启mysql服务之后则恢复默认值,但可以通过修改配置文件(可以在配置文件my.cnf中添加max_allowed_packet=150M即可)来达到永久有效的目的,可其实我们并不是经常有这种大量数据的导入操作,所以个人觉得通过命令行使得当前配置生效即可,没有必要修改配置文件。

2006 MySQL server has gone away & Got a packet

2006 MySQL server has gone away & Got a packet

2006 - MySQL server has gone away

max_allowed_packet=500M

[Err] 1153 - Got a packet bigger than ''max_allowed_packet'' bytes

修改完记得重启数据库

重启数据库:

 /etc/init.d/mysql restart

查看状态:

 /etc/init.d/mysql status

1071 - Specified key was too long; max key length is 767 bytes

原因

数据库表采用 utf8 编码,其中 varchar (255) 的 column 进行了唯一键索引

而 mysql 默认情况下单个列的索引不能超过 767 位 (不同版本可能存在差异)

于是 utf8 字符编码下,255*3 byte 超过限制

解决

1  使用 innodb 引擎;

2  启用 innodb_large_prefix 选项,将约束项扩展至 3072byte;

3  重新创建数据库;

my.cnf 配置:

default-storage-engine=INNODB

innodb_large_prefix=on

 

一般情况下不建议使用这么长的索引,对性能有一定影响;

参考文档:

https://dev.mysql.com/doc/refman/5.5/en/innodb-restrictions.html

 

Django (2006, ''MySQL server has gone away'') 本地重现与解决

Django (2006, ''MySQL server has gone away'') 本地重现与解决

最近我们的Django项目供Java Sofa应用进行tr调用时, 经常会出现一个异常: django.db.utils.OperationalError: (2006, ''MySQL server has gone away''). 本文记录了分析, 本地重现与解决此问题的全过程.

原因分析:

Django在1.6引入长链接(Persistent connections)的概念, 可以在一个HTTP请求中一直用同一个连接对数据库进行读写操作.
但我们的应用对数据库的操作太不频繁了, 两次操作数据库的间隔大于MySQL配置的超时时间(默认为8个小时), 导致下一次操作数据库时的connection过期失效.

Our databases have a 300-second (5-minute) timeout on inactive connections. That means, if you open a connection to the database, and then you don’t do anything with it for 5 minutes, then the server will disconnect, and the next time you try to execute a query, it will fail.

重现问题:

设置mysql wait_timeout为10s

在macOS上的mysql配置文件路径: /usr/local/etc/my.cnf

1
2
3
4
5
6
# Default Homebrew MySQL server config
[mysqld]
# Only allow connections from localhost
bind-address = 127.0.0.1
wait_timeout = 10
interactive_timeout = 10

 

重启mysql:

1
2
3
4
➜  ~ brew services restart mysql
Stopping `mysql`... (might take a while)
==> Successfully stopped `mysql` (label: homebrew.mxcl.mysql)
==> Successfully started `mysql` (label: homebrew.mxcl.mysql)

 

检查wait_timeout的值是否已被更新.

1
2
3
4
5
6
7
8
9
mysql> show variables like ''%wait_timeout%'';
+--------------------------+----------+
| Variable_name | Value |
+--------------------------+----------+
| innodb_lock_wait_timeout | 50 |
| lock_wait_timeout | 31536000 |
| wait_timeout | 10 |
+--------------------------+----------+
3 rows in set (0.00 sec)

 

重现exception:

1
2
3
4
5
6
7
8
9
10
11
12
>>> XXX.objects.exists()
True
>>> import time
>>> time.sleep(15)
>>> XXX.objects.exists()
True
>>> XXX.objects.exists()
...
django.db.utils.OperationalError: (2013, ''Lost connection to MySQL server during query'')
>>> XXX.objects.exists()
...
django.db.utils.OperationalError: (2006, ''MySQL server has gone away'')

有意思的一个点是, sleep 10s 之后, 第一次操作数据库, 会出现(2013, ''Lost connection to MySQL server during query’)异常. 之后再操作数据库, 才会抛出(2006, ''MySQL server has gone away’)异常.

解决问题:

第一个最暴力的方法就是增加mysql的wait_timeout让mysql不要太快放弃连接. 感觉不太靠谱, 因为不能杜绝这种Exception的发生.

第二个办法就是手动把connection直接关闭:

1
2
3
4
5
6
7
8
>>> Alarm.objects.exists()
True
>>> from django.db import connection
>>> connection.close()
>>> time.sleep(10)
>>> Alarm.objects.exists()
True
>>>

 

发现不会出现(2006, ''MySQL server has gone away’)异常了, 但总感觉还是不够优雅.
最终决定在客户端(Django), 设置超时时间(CONN_MAX_AGE: 5)比mysql服务端(wait_timeout = 10)小:

1
2
3
4
5
6
7
DATABASES = {
''default'': {
''ENGINE'': ''django.db.backends.mysql'',
''CONN_MAX_AGE'': 5,
<other params here>
}
}

 

但很奇怪没有生效??? 看了源代码, 发现只有在request_started(HTTP request)和request_finished的时候, 在close_if_unusable_or_obsolete才用到CONN_MAX_AGE并去验证时间关闭connection.

具体代码见: python3.6/site-packages/django/db/__init__.py#64

1
2
3
4
5
6
7
8
9
# Register an event to reset transaction state and close connections past
# their lifetime.
def close_old_connections(**kwargs):
for conn in connections.all():
conn.close_if_unusable_or_obsolete()


signals.request_started.connect(close_old_connections)
signals.request_finished.connect(close_old_connections)

 

而我的代码是处理一个任务而不是HTTP请求, 所以不会触发这个signal. 于是我写了一个装饰器, 在任务的开始和结束的时候, 关闭所有数据库连接.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from django.db import connections


# ref: django.db.close_old_connections
def close_old_connections():
for conn in connections.all():
conn.close_if_unusable_or_obsolete()


def handle_db_connections(func):
def func_wrapper(request):
close_old_connections()
result = func(request)
close_old_connections()

return result

return func_wrapper

# ------割-------
@handle_db_connections
def process_trsbrain_request(request):
...

 

ps. CONN_MAX_AGE默认其实为0, 意味着默认在http请求和结束时会关闭所有数据库连接.

其他:

django.db中connection和connections的区别???

  1. connection对应的是默认数据库的连接, 用代码表示就是connections[DEFAULT_DB_ALIAS]
  2. connections对应的是setting.DATABASES中所有数据库的connection

ERROR 2006 (HY000): MySQL server has gone away No

ERROR 2006 (HY000): MySQL server has gone away No


 我的问题是参数max_allowed_packet=4M太小导致,同过在my.cnf里添加max_allowed_packet=16M重启mysql服务器生效,下面文件设置mysql> set global max_allowed_packet=1024*1024*16;重启后不生效。

(都忘记当时啥状况了)

转文:http://ronaldbradford.com/blog/sqlstatehy000-general-error-2006-mysql-server-has-gone-away-2013-01-02/

 

原因1. MySQL 服务宕了

判断是否属于这个原因的方法很简单,执行以下命令,查看mysql的运行时长

$ mysql -uroot -p -e "show global status like ''uptime'';" +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Uptime | 68928 | +---------------+-------+ 1 row in set (0.04 sec)


或者查看MySQL的报错日志,看看有没有重启的信息

$ tail /var/log/mysql/error.log 130101 22:22:30 InnoDB: Initializing buffer pool, size = 256.0M 130101 22:22:30 InnoDB: Completed initialization of buffer pool 130101 22:22:30 InnoDB: highest supported file format is Barracuda. 130101 22:22:30 InnoDB: 1.1.8 started; log sequence number 63444325509 130101 22:22:30 [Note] Server hostname (bind-address): ''127.0.0.1''; port: 3306 130101 22:22:30 [Note] - ''127.0.0.1'' resolves to ''127.0.0.1''; 130101 22:22:30 [Note] Server socket created on IP: ''127.0.0.1''. 130101 22:22:30 [Note] Event Scheduler: Loaded 0 events 130101 22:22:30 [Note] /usr/sbin/mysqld: ready for connections. Version: ''5.5.28-cll'' socket: ''/var/lib/mysql/mysql.sock'' port: 3306 MySQL Community Server (GPL)

如果uptime数值很大,表明mysql服务运行了很久了。说明最近服务没有重启过。

如果日志没有相关信息,也表名mysql服务最近没有重启过,可以继续检查下面几项内容。

2. 连接超时

如果程序使用的是长连接,则这种情况的可能性会比较大。

即,某个长连接很久没有新的请求发起,达到了server端的timeout,被server强行关闭。

此后再通过这个connection发起查询的时候,就会报错server has gone away


$ mysql -uroot -p -e "show global variables like ''%timeout'';" +----------------------------+----------+ | Variable_name | Value | +----------------------------+----------+ | connect_timeout | 30 | | delayed_insert_timeout | 300 | | innodb_lock_wait_timeout | 50 | | innodb_rollback_on_timeout | OFF | | interactive_timeout | 28800 | | lock_wait_timeout | 31536000 | | net_read_timeout | 30 | | net_write_timeout | 60 | | slave_net_timeout | 3600 | | wait_timeout | 28800 | +----------------------------+----------+

mysql> SET SESSION wait_timeout=5; ## Wait 10 seconds mysql> SELECT NOW(); ERROR 2006 (HY000): MySQL server has gone away No connection. Trying to reconnect... Connection id: 132361 Current database: *** NONE *** +---------------------+ | NOW() | +---------------------+ | 2013-01-02 11:31:15 | +---------------------+ 1 row in set (0.00 sec)

3. 进程在server端被主动kill

这种情况和情况2相似,只是发起者是DBA或者其他job。发现有长时间的慢查询执行kill xxx导致。

$ mysql -uroot -p -e "show global status like ''com_kill''" +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Com_kill | 0 | +---------------+-------+

4. Your SQL statement was too large.

当查询的结果集超过 max_allowed_packet 也会出现这样的报错。定位方法是打出相关报错的语句。

用select * into outfile 的方式导出到文件,查看文件大小是否超过 max_allowed_packet ,如果超过则需要调整参数,或者优化语句。

mysql> show global variables like ''max_allowed_packet''; +--------------------+---------+ | Variable_name | Value | +--------------------+---------+ | max_allowed_packet | 1048576 | +--------------------+---------+ 1 row in set (0.00 sec)

修改参数:

mysql> set global max_allowed_packet=1024*1024*16; mysql> show global variables like ''max_allowed_packet''; +--------------------+----------+ | Variable_name | Value | +--------------------+----------+ | max_allowed_packet | 16777216 | +--------------------+----------+ 1 row in set (0.00 sec)


MySQL Backup--Xtrabackup备份异常(MySQL Server has gone away)

MySQL Backup--Xtrabackup备份异常(MySQL Server has gone away)

错误场景
MySQL 版本:5.7.24
XtraBackup 版本:2.4.8
CentOS 版本:6.5

MySQL需要新增一个从库,为避免XtraBackup备份影响生产,选择在从库上进行备份,备份脚本为:

innobackupex \
--socket=${mysql_socket} \
--user=${mysql_user} \
--password=${mysql_pwd} \
--defaults-file=${mysql_config_file} \
--slave-info \
${backup_dir}

之前一直运行正常的脚本,最近却频繁报错:

failed to execute query SET SESSION lock_wait_timeout=31536000,MySQL server has gone away.

 

问题原因

MySQL报gone away错误的常见因素

1、MySQL连接超时(受参数wait_timeout和interactive_timeout控制)
2、MySQL连接被KILL
3、MySQL实例重启

 

排查问题后发现:

1、从库上没有业务操作,不存才超大事务。
2、从库上SQL线程应用主库BINLOG,但主库没有超大事务也没有DDL操作。
3、备份账号有管理员权限,有足够权限执行SET操作。
4、SET操作失败概率最近一段时间较高。
5、MySQL实例正常,连接超时时间配置较长。
6、开启通用日志,捕捉到KILL命令,发现自动KILL的程序有BUG

 

问题总结

innobackupex备份过程后期,会使用长连接到MySQL执行查询,在两次执行过程中连接处于SLEEP状态,而部署的自动KILL程序为释放连接会自动KILL这些长时间SLEEP的连接,导致备份失败。

关于MySQL server has gone away错误的解决办法mysql server has gone away什么意思的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于2006 MySQL server has gone away & Got a packet、Django (2006, ''MySQL server has gone away'') 本地重现与解决、ERROR 2006 (HY000): MySQL server has gone away No、MySQL Backup--Xtrabackup备份异常(MySQL Server has gone away)等相关内容,可以在本站寻找。

本文标签: