2016年那次Linux认证考试当中,数据库备份可是必考的实操题目,然而好多考生长达考完都并未弄明白——为啥脚本运行不顺畅、备份老是遭遇失败、10份保留却变成10倍像垃圾一样的东西?今天,我们就要去拆解这个虽然被培训机构讲得稀松平常、但自己动手就会出现问题的MySQL全量备份脚本,把其中的坑给填平。

脚本开头别硬抄
像用户名、密码、数据库名留白这样,网上流传的脚本模板变量名全部都是空的,你要是直接把它复制进考场,备份出来的文件,不是呈现乱码,就是0字节。在2016年的时候,我帮三个考生排查错误,结果发现他们就连MySQL的登录密码都没有填进去。对于正确的做法而言,首先要去确定MySQL的安装路径,以及登录权限,然后填写实际的IP以及端口,千万别相信那个“要是仅针对数据备份就能够不用去填写”的不实传言,在大多数发行版本的情况下,/usr/local/mysql/bin并不在PATH之中,要是不写上绝对路径,那就等着出现报错的情况吧。
备份命令少用管道
好些教材教导人们使用mysqldump | gzip > file.gz,这本身并没有差错,然而问题在于管道的前后没有添加-h来指定socket或者TCP连接。2016年的时候MySQL 5.6默认是通过socket文件的,如果在脚本当中仅仅写了mysqldump -uroot -p123,可是系统里安装了多个MySQL实例,那么极有可能连接错误的库。我于某电商公司目睹过一回事故,因脚本当中漏写了-h参数,进而将开发库的备份文件覆盖到了生产库,所幸当晚并无促销活动,不然赔付的金额足以购买三台服务器。
另外存在这样一个细节,-B参数起到用于指定进行多个库备份的作用,然而全量备份一般来讲是一次性就对全部库进行备份,在这样的情况下,直接采用--all-databases相比于使用-B再加上循环遍历会更加稳定。在2016年的时候,于某银行外包项目当中,运维人员运用循环备份致使innodb表锁等待超时,在业务处于高峰期时页面出现卡死状况长达15分钟,事后进行复盘发现问题就出在这行循环代码上面。
备份轮转不是数文件夹
留存最新的10份备份并非是仅仅数出10个文件夹就大功告成了。脚本之中那个从9到0的for循环,运用mv来进行目录重命名,首次运行的时候没有问题,然而第二次运行的时候就全然乱了套。这是由于.0目录被重命名成为了.1,新的备份又被写入到了.0之中,可是脚本并没有对.9被覆盖之后的清理工作予以处理。采取的正确方式是,运用date +%Y%m%d_%H%M%S去打时间戳来存储文件,而后借助ls -t | tail -n +11 | xargs rm -f将旧文件予以删除。在二零一六年的时候,于腾讯云开发者社区存在一篇文章有专门对这两种轮转方式进行比较,时间戳法相较于目录移位法能够节省一半的磁盘I/O。
并且数量众多的考生将这样一点给忽略了:留存10次备份并非意味着仅仅留存10个文件。要是每一天进行一次备份,历经10天那么就是10份,然而脚本之中却创建了从.0直至.10总共11个目录,无故多留存了一份。这种边界方面的错误在笔试的选择题里展现的出现频率是极高的,在2016年下半年的时候红帽考试存有类似的题目,其正确的选项是“采用find加上-mtime +10来实施删除”。
压缩参数省空间
gzip压缩级别默认设定为6,然而在生产环境当中常常是追求速度占据优先地位,2016年美团数据库团队曾分享过他们的压测数据,使用gzip -1相比于默认级别能够节省40%的时间,压缩率仅仅相差5%左右,对于文本类的SQL备份而言已然足够。但脚本里面仅仅写了GZIP="/bin/gzip",在后面调用的时候没有添加任何参数,这等同于白白浪费了调优的机会。
还有更关键的一点,那就是所提及的压缩究竟应当是在内存当中完成之后再进行落盘操作呢,还是先将其dump成为文本格式之后才开展压缩工作呢?若是选择后者的话,就会产生规模巨大的临时文件,在2016年那个时候机械硬盘仍然属于主流存储设备,某医疗系统出现如此情况是因为备份所产生的临时文件把根分区给撑爆了,这样一来就致使MySQL直接处于宕机状态。而正确的做法是采用mysqldump | gzip > 目标文件这种方式,全程都能够保持流式处理,进而不会占用额外的磁盘空间。
定时任务要测试
在crontab里书写为00 5 * root //.sh,将路径写成双斜杠这属于明显的差错。在2016年期间我从事Linux认证实操的监考工作,起码有20%的考生于此处丢失分数。正确的路径应该是绝对路径,就像/opt/backup/backup.sh这样,并且最好是在crontab里把输出重新定向到日志文件,不然要是备份失败了那你就连错误提示都没办法看到。另外,可别忘却mysqldump存在那交互式终端的要求?实则并非如此,然而它却有着加载用户profile环境变量的需求,所以在脚本开端建议添加上. /etc/profile以及.~/.bash_profile,以此防止命令寻觅不到。
脚本健壮性不够
全量备份最为突出的痛点在于锁表,在2016年时主流的MySQL仍广泛运用MyISAM表,默认情况下mysqldump会添加读锁,致使在备份期间网站仅能够进行读取操作而无法进行写入操作,对于一个拥有5000万行记录的文章表而言,备份耗费时间为3分钟,在这三分钟的时间段内所有用户发帖均会失败,应当添加--single-transaction参数,借助InnoDB的MVCC机制实现热备,从而不对业务表进行锁定。2016年的认证考试里,这个细节已然是考点,许多教材仅仅提及了--lock-tables=false,然而却并未对何时使用以及为何使用作出解释。
再者脚本里头压根不存在异常处理的情况,要是MySQL连接出现超时现象,那备份文件会成为一个空文件,到了第二天进行轮转操作的时候还会把旧文件给删除掉,这就等同于数据全部丢失了,起码得在mysqldump命令后面 添加|| exit 1,并且在crontab里面对备份文件大小进行监控,一旦小于1KB就发送报警邮件。
平素你运用MySQL备份脚本时,究竟是更为担忧磁盘空间出现被撑满的状况,还是更加惧怕备份时段业务产生不流畅的情况呢?欢迎于评论区域分享你曾遇到过的麻烦,通过点赞让更多同行业者躲开这些隐患。

Comments NOTHING