数据恢复binlog回放的一个报错问题
今天早上在线上进行数据恢复的时候,看到了一个报错,发现挺有意思的,就给记录下来了。废话不多说,直接说场景。
01
问题描述
真实的案例如下:
某个数据库在回放binlog的时候,总是回放到一个指定的binlog行数发生报错,报错的信息是:
ERROR 2006 (HY000) at line 7610607: MySQL server has gone away
02
思路一
看到这个错误,我的第一反应是那两个timeout参数,分别是wait_timeout和interactive_timeout,其中:
参数wait_timeout指的是如果客户端太长时间没动静,连接器就会自动将它断开,默认值是8小时,主要针对jdbc、mysql api这种连接;
参数interactive_timeout主要针对交互式连接,类似mysql客户端这种连接,默认值也是8小时。
如果连接的闲置时间大于这两个参数值,那么对应的连接将会被打断。经过查看,这两个参数的值都没有人为改变过,都是28800,也就是8小时。看来这个错误,和这两个参数的关系不大。
根据报错,查看binlog的固定行数的信息,经过查询,发现该位置的binlog里面的内容是一个很大的SQL,SQL内容我这里就不贴出来了,在binlog中,这些内容都被解析成了一些乱码,类似下面这样:
代码语言:javascript复制BINLOG '
SnlPXg9GjD27dwAAAHsAAAABAAQANS43LjIwLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
ATBGvNA=
啰嗦一句,如果你想看到这些内容,可以使用:
mysqlbinlog --base64-output=DECODE-ROWS -v
这个命令来进行查看。
03
思路二
看到了这个比较大的SQL内容,又想到一个参数,就是MySQL客户端和服务器每次通信的最大通信包参数:max_allowed_packet,于是查询了一下官方文档关于这个参数的说明,摘取了几个关键部分如下:
1、该参数的默认值是4MB,小的默认值是为了过滤那些比较大的通信包(过大的通信包被认为是有问题的)
2、当表中存在blob字段的时候,通常需要增加这个参数值,通信协议限制该参数的最大值为1G,一般设置为1024的整数倍
3、通常情况下,更改这个参数的时候,需要在server段和client一起改,一般client端修改方法是写在配置文件里面或者登陆服务端的时候写在命令行中,server端的修改一般使用set global 参数的方式或者配置文件的方式来修改。
4、mysql客户端上这个参数默认值是16M,mysqldump客户端上这个参数默认值是24M
看到这里,我做了个实验,先将server端的值改大点试试,
set global max_allowed_packet=1073741824;
将server端的max_allowed_packet值改为1G之后,报错信息发生了变化:
ERROR 1153 (08S01) at line 7610607: Got a packet bigger than 'max_allowed_packet' bytes
这个报错信息就比较明显了,就是发现了一个大于该参数指定值的通信包。这里说明server端的修改已经生效了。下面修改client端就好了。
重新修改配置文件:
[mysqldump]
quick
max_allowed_packet = 512M
[mysql]
max_allowed_packet = 512M
修改完成之后,重新连接mysql server,重放binlog,发现这个问题已经解决。
除此之外,需要注意的是,我们也可以通过手工指定的方法来进行登陆,而不用修改配置文件,例如:
mysql -utest -ppassword -h127.0.0.1 --max-allowed-packet=512M