关于定时任务:故障分析-MySQL-备份文件静默损坏一例分析

44次阅读

共计 1877 个字符,预计需要花费 5 分钟才能阅读完成。

作者:付祥

现居珠海,次要负责 Oracle、MySQL、mongoDB 和 Redis 保护工作。

本文起源:原创投稿

* 爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。


背景

线上一套 MySQL 打算降级到 8.0,通过备份还原搭建一个测试环境,用于降级测试。数据库采纳 xtrabackup 每天进行全备,压缩备份文件约 300G,解压到一半就报错了:

gzip: stdin: invalid compressed data--format violated
tar: Unexpected EOF in archive
tar: Unexpected EOF in archive
tar: Error is not recoverable: exiting now

刚开始认为只是这个备份文件不残缺,又找了前一天备份文件,解压过程中也报了同样的谬误,备份文件比拟大,无疑减少了排障工夫。

故障剖析

备份脚本通过 crontab 每天凌晨执行,线上都是同一套备份脚本,不同我的项目时常做备份数据还原,还是头一次遇到备份文件解压失败景象,查看了脚本,每个要害阶段都做了状态码判断是否胜利,若失败就告警,同时对 xtrabackup 备份日志最初一行是否蕴含 completed OK 关键词也做了判断,要害备份脚本如下:

xtrabackup xxx --stream=tar  --no-timestamp $bkdir 2> xxx.log | gzip - > xxx.tar.gz

近期也没收到失败告警,阐明备份脚本是执行胜利了的,感觉太奇怪了,查看定时工作日志,发现同一工作同一时间点居然启了 2 次:

[root@localhost backup]# grep backup /var/log/cron
Mar  6 00:00:01 localhost CROND[6212]: (root) CMD (sh xxx/mysql_ftp_backup.sh || echo 1 > xxx/err.log)
Mar  6 00:00:01 localhost CROND[6229]: (root) CMD (sh xxx/mysql_ftp_backup.sh || echo 1 > xxx/err.log)
Mar  7 00:00:01 localhost CROND[5387]: (root) CMD (sh xxx/mysql_ftp_backup.sh || echo 1 > xxx/err.log)
Mar  7 00:00:01 localhost CROND[5420]: (root) CMD (sh xxx/mysql_ftp_backup.sh || echo 1 > xxx/err.log)

crond 服务每次同时拉起 2 个过程执行备份,并发地往同一个压缩文件 xxx.tar.gz 写数据,备份数据互相笼罩,导致备份文件损坏,每天看似备份胜利的工作,其实备份都是有效的,这也阐明了定期备份复原演练的重要性。为何定时工作同一时间点会启动 2 次?查看 crond 过程:

[root@localhost backup]# ps -ef|grep crond |grep -v grep
root 2883 1 0 2018 ? 01:42:46 crond 
root 17293 1 0 2022 ? 00:43:22 crond

原来是因为系统启动了 2 个 crond 过程,kill crond 过程后重启,再次查看只有一个 crond 过程:

[root@localhost backup]# service crond stop
Stopping crond:                                            [OK]

[root@localhost backup]# ps -ef|grep crond
root      2883     1  0  2018 ?        01:42:46 crond
root     31486 31856  0 10:59 pts/2    00:00:00 grep crond

[root@localhost backup]# kill 2883
[root@localhost backup]# ps -ef|grep crond
root     31572 31856  0 10:59 pts/2    00:00:00 grep crond

[root@localhost backup]# service crond start
Starting crond:                                            [OK]
[root@localhost backup]# ps -ef|grep crond
root     31632     1  0 10:59 ?        00:00:00 crond
root     31639 31856  0 11:00 pts/2    00:00:00 grep crond

总结

为了确保备份无效,须要做如下改良:

1、flock 给脚本执行加互斥锁,确保一个工夫点只有 1 个过程运行。

2、定期做备份复原演练。

3、减少 crond 过程监控,不等于 1 告警。

正文完
 0