Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

使用 cron 定时备份 MySQL 数据库(使用 Ubuntu 系统) #153

Open
Qingquan-Li opened this issue May 7, 2020 · 0 comments
Open
Labels

Comments

@Qingquan-Li
Copy link
Owner

Qingquan-Li commented May 7, 2020

环境:

  • Ubuntu 16.04 LTS
  • mysql-server-5.7

一、自动备份MySQL数据库的 .sh 脚本

注意:运行此脚本的系统(这里是 Ubuntu )上需要先安装好 MySQL,否则将会报错:mysql: command not found 。参考:FatliTalk - Ubuntu 安装 MySQL 5.7

mysql_user="root" #需要备份的MySQL的用户名,这里用户名为root
mysql_password="password" #需要备份的MySQL用户密码
mysql_host="IP地址" #在运行MySQL的服务器进行本地备份,IP地址填localhost";在另一台服务器对MySQL进行备份,则填写运行MySQL的服务器的IP地址
mysql_port="3306"
mysql_charset="utf8" #MySQL编码
backup_db_arr=("db01") #要备份的数据库名称,多个用空格分开隔开 如("db01" "db02" "db03")
backup_location=~/db01_backup #备份数据存放位置,末尾请不要带"/",如果没有db01_backup这个文件夹,程序会自动创建文件夹
expire_backup_delete="ON" #是否开启过期备份删除,ON为开启,OFF为关闭
expire_days=7 #过期时间天数。默认为三天,此项只有在expire_backup_delete开启时有效

# 本行开始以下不需要修改
backup_time=`date +%Y%m%d%H%M` #定义备份详细时间
backup_Ymd=`date +%Y-%m-%d` #定义备份目录中的年月日时间
backup_7ago=`date -d '7 days ago' +%Y-%m-%d` #7天之前的日期
backup_dir=$backup_location/$backup_Ymd #备份文件夹全路径
welcome_msg="Welcome to use MySQL backup tools!" #欢迎语

# 判断MYSQL是否启动,mysql没有启动则备份退出
# 注意:运行此脚本的系统上需要先安装好MySQL,否则将会报错:mysql: command not found
mysql_ps=`ps -ef |grep mysql |wc -l`
mysql_listen=`netstat -an |grep LISTEN |grep $mysql_port|wc -l`
if [ [$mysql_ps == 0] -o [$mysql_listen == 0] ]; then
echo "ERROR:MySQL is not running! backup stop!"
exit
else
echo $welcome_msg
fi

# 连接到mysql数据库,无法连接则备份退出
mysql -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password <<end
use mysql;
select host,user from user where user='root' and host='localhost';
exit
end
 
flag=`echo $?`
if [ $flag != "0" ]; then
echo "ERROR:Can't connect mysql server! backup stop!"
exit
else
echo "MySQL connect ok! Please wait......"
# 判断有没有定义备份的数据库,如果定义则开始备份,否则退出备份
if [ "$backup_db_arr" != "" ];then
#dbnames=$(cut -d ',' -f1-5 $backup_database)
#echo "arr is (${backup_db_arr[@]})"
for dbname in ${backup_db_arr[@]}
do
echo "database $dbname backup start..."
`mkdir -p $backup_dir`
`mysqldump -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password $dbname --default-character-set=$mysql_charset | gzip > $backup_dir/$dbname-$backup_time.sql.gz`
flag=`echo $?`
if [ $flag == "0" ];then
echo "database $dbname success backup to $backup_dir/$dbname-$backup_time.sql.gz"
else
echo "database $dbname backup fail!"
fi
 
done
else
echo "ERROR:No database to backup! backup stop"
exit
fi
# 如果开启了删除过期备份,则进行删除操作
if [ "$expire_backup_delete" == "ON" -a "$backup_location" != "" ];then
`find $backup_location/ -type d -mtime +$expire_days | xargs rm -rf`
echo "Expired backup data delete complete!"
# 移动过期备份到 ~/delete 目录下,而不是直接删除:
# `find $backup_location/ -type d -mtime +$expire_days | xargs -I {} mv {} ~/delete`
# echo "Expired backup data move to delete directory complete!"
fi
echo "All database backup success! Thank you!"
exit
fi

二、编写 crontab 文件定时执行脚本

参考:

【crontab 文件格式】时间+动作:

# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
# │ │ │ │ │                                       7 is also Sunday on some systems)
# │ │ │ │ │
# │ │ │ │ │
# * * * * * command to execute

【实例】编写 crontab 脚本文件,定时执行 MySQL 备份脚本:

$ crontab -e # 编辑当前用户的crontab文件
# 进入 vim 进行编辑,例如每天凌晨 02:00 执行 ~/db_backup 目录下
# 的 mysqlbackup.sh 脚本:00 02 * * * cd ~/db_backup && ./mysqlbackup.sh

$ crontab -l # 列出当前用户编辑的crontab文件的内容
00 02 * * * cd ~/db_backup && ./mysqlbackup.sh

$ crontab -r # 从/var/spool/cron目录中删除某个用户的crontab文件,如果不指定用户,则默认删除当前用户的crontab文件(上面 crontab -e 创建的 crontab 脚本文件)。

三、Ubuntu下cron定时任务脚本不被执行的问题

参考:

1. 测试-找出问题:

$ crontab -l
* * * * * echo "Hello"
# tail 命令:显示指定文件的末尾10行,control+C退出(这里使用的是本地虚拟机上的Ubuntu)
$ tail /var/log/syslog
May  8 02:26:01 fatli-vm-ubuntu CRON[63924]: (fatli) CMD (echo "Hello")
May  8 02:26:01 fatli-vm-ubuntu CRON[63923]: (CRON) info (No MTA installed, discarding output)
May  8 02:27:01 fatli-vm-ubuntu CRON[63928]: (fatli) CMD (echo "Hello")
May  8 02:27:01 fatli-vm-ubuntu CRON[63927]: (CRON) info (No MTA installed, discarding output)
May  8 02:28:01 fatli-vm-ubuntu CRON[63933]: (fatli) CMD (echo "Hello")
May  8 02:28:01 fatli-vm-ubuntu CRON[63932]: (CRON) info (No MTA installed, discarding output)
May  8 02:29:01 fatli-vm-ubuntu CRON[63937]: (fatli) CMD (echo "Hello")
May  8 02:29:01 fatli-vm-ubuntu CRON[63936]: (CRON) info (No MTA installed, discarding output)
May  8 02:30:01 fatli-vm-ubuntu CRON[63941]: (fatli) CMD (echo "Hello")
May  8 02:30:01 fatli-vm-ubuntu CRON[63940]: (CRON) info (No MTA installed, discarding output)
# 发现原因是:Ubuntu 不同于其他 Linux 发行版,Ubuntu 默认没有安装包含 MTA (Mail Transfer Agent)的邮件服务,导致 cron 不能发送通知(日志)给用户。
$ crontab -e
# 修改crontab脚本文件:* * * * * echo "Hello world!" >> ~/db_backup/cron4test.log
# 再次执行,发现每分钟都会打印一行 Hello world! 到 cron4test.log 文件中,
# 并且执行 `$ tail /var/log/syslog` ,也不见报错 `No MTA installed` 了。

# 注意此处 `>> cron4test.log` 生成的日志文件中,会记录每次执行 crontab 脚本文件的日志输出,每分钟打印一行 "Hello world!";
# 如果改为 `>cron4test.log` 则只记录最近一次执行 crontab 脚本文件的日志输出,也就是永远只有一行 “Hello world!" 。

2. 解决方案:修改 crontab 脚本文件:

$ crontab -e
# 脚本由:00 02 * * * cd ~/db_backup && ./mysqlbackup.sh
# 修改为:00 02 * * * cd ~/db_backup && ./mysqlbackup.sh >> cron4mysqlbackup.log
# 把日志记录在 cron4mysqlbackup.log 中而不是通过邮件发送;或者忽略其日志记录:
# 修改为:00 02 * * * cd ~/db_backup && ./mysqlbackup.sh >/dev/null 2>&1
# /dev/null 2>&1 作用参考:linuxtools-rst.readthedocs.io/zh_CN/latest/tool/crontab.html#id22
# /dev/null 参考:zh.wikipedia.org/wiki//dev/null
# 2>&1 的作用参考:stackoverflow.com/questions/818255/in-the-shell-what-does-21-mean

重启一下 cron 服务(新创建的 cron job,不会马上执行,要过1分钟左右才执行):

$ sudo /etc/init.d/cron restart
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant