几天前收到某个业务项目,MySQL数据库逻辑备份mysqldump备份失败的邮件,本是在休假,但本着工作认真负责,7*24小时不间断运维的高尚职业情操,开始了DBA的排错之路(一开始数据库的备份都是成功的,巧的是我休假就出问题,怀疑是数据量又有增长)

首先我们了解下mysqldump备份,数据流向的一个过程:MySQL Server端从数据文件中检索出数据,然后分批将数据返回给mysqldump客户端,然后mysqldump再把数据写入到NFS上。一般情况下存储不是SSD或者是普通磁盘,那么向NFS上写入数据比Server端检索完数据发送给mysqldump客户端要慢得多,这就有可能mysqldump无法及时接收MySQL Server端发送过来的数据,导致Server端检索出来的数据在内存中积压等待发送。当超过等待的时间net_write_timeout(默认60s)时就连接断开,同时抛出错误。

1、定位问题

登录到机器上,先查看了备份文件的逻辑,再查看备份的日志和备份文件大小,确认备份失败并定位到是备份命令mysqldump行执行一半失败(根据备份文件较之前的几天减少了一半且脚本运行日志来断定)。凌晨的备份无效,因而手动触发脚本执行备份,发现了报错如下:

[root@mysql_query hk_sa]# bash /opt/shells/mysqldump.sh
Warning: Using a password on the command line interface can be insecure.
mysqldump: Error : Lost connection to MySQL server during query when dumping table `rrd_api_log` at row: 2821866

2、排查问题

查看备份失败的表的行数为4982704,查看手动备份失败处的行信息是2017-02-05 04:03:18写入,之前都没有出现过这个备份失败的问题。于是开始怀疑是不是最近数据增长太大或者表的字段太宽的问题(其他数据库的表更大,有的甚至达到400G也没有出现过这个问题,表数据量太大的可能性不大,但单行备份失败,怀疑大字段的问题)

查看表结构如下:

[root@localhost] | 08:42:21 | [heika0516] > desc rrd_api_log;
+---------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| api_command | varchar(30) | NO | | NULL | |
| request_info | text | NO | | NULL | |
| response_info | text | NO | | NULL | |
| create_time | datetime | NO | | NULL | |
+---------------+-------------+------+-----+---------+----------------+
5 rows in set (0.01 sec) 

方向定了剩下的就是验证自己的猜想了,于是我开始查找资料,果然被我百度到了一些有价值的东西,包括MySQL官方的一些说法:https://bugs.mysql.com/bug.php?id=46103。其中大概的意思就是这个问题老版本会出现,可以调整两个参数net_write_timeout或者max_allowed_packet的值大一些。net_write_timeout的默认值是60s,而max_allowed_packet的默认值是67108864,又是一通查资料后发现,有些前辈调整max_allowed_packet无效,而调整net_write_timeout才有效,于是我也站着巨人的肩膀上搞了一把,果然备份成功了,挺过了休假时被烦恼的问题。

然而新的问题又出来了,很多前辈都讲增大net_write_timeout的值,Server端会消耗更多的内存甚至导致swap的使用影响性能,但又不确定是不是参数调整所致,存在潜在的风险。不过这种说法我并不同意,因为我执行的过程中发现,MEM的free反而变多了,你没有听错真的变多了。

#mysqldump备份执行前
[root@mysql_query hk_sa]# free -m
total used free shared buffers cached
Mem: 16080 13305 2775 0 121 3729
-/+ buffers/cache: 9454 6626
Swap: 8191 349 7842 #增大了net_write_timeout的值
[root@localhost] | 08:51:53 | [(none)] > set @@global.net_write_timeout=500;
Query OK, 0 rows affected (0.01 sec) #bash完脚本发现备份OK的
[root@mysql_query hk_sa]# ls -lh /opt/app/mysql/data/heika0516/rrd_api_log.ibd
-rw-r--r-- 1 mysql mysql 4.1G Aug 7 22:03 /opt/app/mysql/data/heika0516/rrd_api_log.ibd #mysqldump备份执行后
[root@mysql_query hk_sa]# free -m
total used free shared buffers cached
Mem: 16080 12434 3646 0 93 2890
-/+ buffers/cache: 9450 6630
Swap: 8191 349 7842

  到此为止,mysqldump备份失败确实是解决,但是前辈们反映的问题是消耗更多的内存,到我这反而释放了更多的内存,这样修改参数终究是会存在安全隐患,且这个参数会影响所有的会话连接。那就先不管了,过个好假期再搞。不过我始终有个疑问,我这维护的400G的大表,且部分表比这更大,也有大字段就没出现过这个问题,怎么会突然出现呢,因此我怀疑不是表数据过多的问题,还是大字段的问题。

休假回来后,立马开始test排错的工作,先分析确认好切入点,我就把net_write_timeout的值改为默认60,但这样备份肯定会失败的,于是想到了max_allowed_packet参数,但全局调整这个参数,对网络发包和各个会话也有影响,继续对mysqldump这个备份进行调研,居然让我发现了一个牛逼的可接参数max_allowed_packet,在mysqldump后面加了这个选项,值大小大家可以根据表的大小进行设置,我这里给的500M,至此问题彻底解决了,也没有改变参数的全局值影响会话。

mysqldump备份表中有大字段失败的排错过程的更多相关文章

  1. 关于mysql中修改某个字段类型,以及备份表中数据到新建的表中,从新建的表中移除数据到修改过的表中

    1:修改表中某个字段的类型 alter table usertable MODIFY dddd VARCHAR(50); 其中MODIFY是指修改表中字段的属性 alter表示修改表的意思 2:备份表 ...

  2. mysql向表中某字段后追加一段字符串:

    mysql向表中某字段后追加一段字符串:update table_name set field=CONCAT(field,'',str) mysql 向表中某字段前加字符串update table_n ...

  3. 解决SQL server 2014 修改表中的字段,无法保存的问题。

    修改PROJECT表中的字段,保存时,弹出上面的窗体,无法保存. 解决方法为:[工具]->[选项]->[设计器]中,去掉“阻止保存要求重新创建表的更改”前的勾选.

  4. mongoDB删除表中一个字段

    使用update命令 update命令 update命令格式: db.collection.update(criteria,objNew,upsert,multi) 参数说明: criteria:查询 ...

  5. c++获取sqlite3数据库表中所有字段的方法

    常用方法: 1.使用sqlite3_get_table函数 2.获取sqlite创建表的sql语句字符串,然后进行解析获取到相应的字段 3.采用配置文件的方式,将所有字段名写入配置文件 方法1:使用s ...

  6. syscolumns表中所有字段的意思

    --syscolumns表中所有字段的意思 name sysname --列名或过程参数的名称. id int --该列所属的表对象 ID,或与该参数关联的存储过程 ID. xtype tinyint ...

  7. Oracle中使用游标转换数据表中指定字段内容格式(拼音转数字)

    应用场景:将数据表TB_USER中字段NNDP的内容中为[sannanyinv]转换为[3男1女] 主要脚本:一个游标脚本+分割字符串函数+拼音转数字脚本 操作步骤如下: 1.创建类型 create ...

  8. 在oracle表中增加字段,并调整字段的顺序

    增加字段的语句很简单,以用户身份连接oracle服务: alter table tablename add(colname coltype); # 填上表名.字段名.字段类型 修改字段顺序前,查看表中 ...

  9. SQL Server 复制表结构以及数据,去除表中重复字段

    --复制另一个数据库中的某张表的结构及数据--select * from Test.dbo.TestTable(查询表中所有数据) --into [表名] 插入当前数据库新表,如果没有该表就创建 se ...

随机推荐

  1. 各个模块的刷新js

    // 更新页面中的subgrid function refreshSubGrid(subgridName) { Xrm.Page.ui.controls.get(subgridName).refres ...

  2. 什么是 ajax?----异步 javascript 和 xml

    GET 用于请求服务器数据 POST 用于上传数据到服务器,或者修改服务器数据 ajax 异步通信,实现页面的局部刷新,按需获取数据,节约带宽,带来更好的用户体验 客户端与服务器在不必刷新浏览器的情况 ...

  3. 【页面置换算法】LRC算法和FIFS算法

    算法介绍 FIFO:该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰.该算法实现简单,只需把一个进程已调入内存的页面,按先后次序链接成一个队列,并设置一个指针,称为替换指针, ...

  4. python | Elasticsearch-dsl常用方法总结(join为案例)

    Elasticsearch DSL是一个高级库,其目的是帮助编写和运行针对Elasticsearch的查询.它建立在官方低级客户端(elasticsearch-py)之上. 它提供了一种更方便和习惯的 ...

  5. verilog中timescale

    1. `timescale `timescale是Verilog中的预编译指令,指定位于它后边的module的时间单位和时间精度,直到遇到新的`timescale指令或者`resetall指令.它的语 ...

  6. [python] bluepy 一款python封装的BLE利器

    1.bluepy 简介 bluepy 是github上一个很好的蓝牙开源项目,其地址在 LINK-1, 其主要功能是用python实现linux上BLE的接口. This is a project t ...

  7. 用Vue2仿京东省市区三级联动效果

    三级联动,随着越来越多的审美,出现了很多种,好多公司都仿着淘宝的三级联动 ,好看时尚,so我们公司也一样……为了贴代码方便,我把写在data里面省市区的json独立了出来,下载贴进去即可用,链接如下 ...

  8. ReactJs和React Native的联系和差异

    1,React Js的目的 是为了使前端的V层更具组件化,能更好的复用,它能够使用简单的html标签创建更多的自定义组件标签,内部绑定事件,同时可以让你从操作dom中解脱出来,只需要操作数据就会改变相 ...

  9. 【RL-TCPnet网络教程】第12章 TCP传输控制协议基础知识

    第12章      TCP传输控制协议基础知识 本章节为大家讲解TCP(Transmission Control Protocol,传输控制协议),通过本章节的学习,需要大家对TCP有个基本的认识,方 ...

  10. 官方JwPlayer去水印步骤

    在前端播放视频,现在用html5的video标签已经是一个不错的选择,不过有时候还是需要用StrobeMediaPlayback.JWPlayer这一类的flash播放器,JWPlayer的免费版本带 ...