docker下使用crontab进行mysql定时备份

it2024-10-31  9

定时备份mysql数据

昨天做了MongoDB的定时备份,紧接着公司的前辈就又让我做一个mysql的定时备份,有了mongo的踩坑经历,这个当然也会简单很多,结果也遇到了不少问题。

1.创建存放备份文件目录

mkdir -p mnt/mysql_bak

2.创建Mongo定时备份脚本

mkdir -p home/crontab #创建文件夹

touch mysql_bak.sh #创建文件

vi home/crontab/mysql_bak.sh #编辑备份脚本

在备份脚本中加入以下内容:

#!/bin/sh # 时间, 做文件名用 dd=`date +%Y-%m-%d` # 容器名叫mysql docker_name=mysql # 存放路径,我这里为了方便,宿主机和容器内的路径都相同 backupdir=/mnt/mysql_bak # 备份到容器的 /mnt/mysql_bak文件夹 docker start mysql docker exec $docker_name mysqldump -uroot -p123456 -A | gzip> $backupdir/mysql_$dd.sql.gz # 复制到宿主机的/mnt/mongo_bak docker cp mysql:$backupdir/mysql_$dd.sql.gz $backupdir/mysql_$dd.sql.gz # 删除docker中的备份数据 docker exec $docker_name rm -rf $backupdir/* # 删除30天前的数据 find $backupdir -name *.sql.gz" -type f -mtime +30 -exec rm -rf {} \; 这里解释下: mysqldump:是mysql 的备份命令 -uroot -p123456 : 分别是数据库账号和密码 -A : 备份全部数据库的表,也可以备份指定的数据库 更换就可以了 gzip : 是备份称.gz的压缩文件 -mtime +30: 按照文件的更改时间来查找文件,+30表示文件更改时间距现在30天以前;如果是 -mmin +30 表示文件更改时间距现在30分钟以前 -exec rm -rf {}; : 表示执行一段shell命令,exec选项后面跟随着所要执行的命令或脚本,然后是一对儿{},一个空格和一个,最后是一个分号

3.修改文件属性,使其可执行

chmod +x /home/crontab/mysql_bak.sh

4.修改/etc/crontab 添加计划任务

crontab -e #编辑定时任务文件

然后在文件下加入以下内容: 30 12 * * * ../.bash_profile;sh /home/crontab/mysql_bak.sh #表示每天12点30执行备份

在这里遇到一个坑,就是发现我的定时任务没有执行,我先手 动执行了以下 bash mysql_bak.sh 证明一下我的脚本是 没有问题的,那么问题就出现系统的调度上,最后发现原来 shell 也要使用环境变量,这是因为cron进程执行的shell 脚本是不会自动加载用户目录下的.profile文件,所以需 要脚本自己加载所需要的环境变量。 就是加上 ../.bash_profile;sh

5.保存退出定时任务文件

在编辑crontab的定时任务文件时,保存退出跟vi是不一样的,先Ctrl+O 【写入】,Ctrl+M【保存】,Ctrl+X【退出】

6.重新启动crond使设置生效

service cron restart #重启服务 或 service cron reload #重新载入配置 service cron start #启动服务

列出定时任务,查看自己修改是否成功 crontab -l #列出crontab文件

到此,整个备份就做好了


这个备份其实并没有刚开始做的时候想的那么简单,遇到一个应该是大家会经常遇到的问题,就是任务调度没有执行,我总结了一下。

1. cron 服务未启动

crontab不是 Linux 内核的功能,而是依赖一个cron服务,这个服务可以启动当然也可以停止。如果停止了就无法执行任何定时任务了。 可以通过以下命令查看: service cron start #启动 service cron stop #停止 service cron restart #重启 service cron reload #重新加载配置

2.文件权限问题

脚本没有x执行权限,解决方法:增加执行权限 chmod +x /home/crontab/mysql_bak.sh

3.时差问题

我在做的时候,发现我打印出来的log的时间与宿主机的时间不同,解决方法:同步时间 1. ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime #修改时区与时间 2. service rsyslog restart #重启

或者 /etc/init.d/rsyslog restart

4.变量问题

在文章上面我也重点说了,解决方法: 加上 ../.bash_profile;sh 即可

5.备份数据为空问题

为了证实自己备份的sql文件没问题,自己连ftp看了下,结果发现文件是空的。然后手动执行脚本文件,再次查看,sql文件又是正常的。 解决方法: 1.把备份脚本中的 -it 去掉 原因:linux执行的时候没有终端设备。我们一般执行docker里的命令时候都喜欢加上 -it 这个参数,这里的-it 就是表示终端设备。所以,如果我们docker执行后台运行的任务或者程序直接去除 -it 这个 2.在备份脚本里面的mysqldump命令前加上绝对路径 例: docker exec $docker_name /root/mysql/bin/mysqldump -uroot -p123456 -A | gzip> $backupdir/mysql_$dd.sql.gz 原因:由于mysqldump存在于全局环境变量mysql的bin下面,故在直接运行时可以识别到mysqldump命令,而在crontab里面无法识别到mysqldump命令。

6.其他问题

或许也会遇到其他问题,可以自行查看日志: 查看cron运行日志 cat /var/log/cron.log ,但是并未找到相关文件,原因是ubuntu默认没有开cron日志,执行命令: sudo vim /etc/rsyslog.d/50-default.conf

找到cron.log相关行,将前面注释符#去掉,保存退出,重启rsyslog: sudo service rsyslog restart 重启cron服务 sudo service cron restart 再次执行 cat /var/log/cron.log 再次查看cron运行日志,log出来了,提示如下信息: No MTA installed, discarding output 执行 apt install postfix 安装Email服务 原因是cron把屏幕输出都发送到email了,而当前环境并未安装email server


文章如有不对或者更好的解决方式,请多多指教

最新回复(0)