如何使用脚本备份 MySQL 数据库?

使用 Shell 脚本对 MySQL 数据库进行备份,可以满足并发量不大的小型数据库。如果是更大数据量且并发量大的生产数据库,建议采用双(多)机热备或专业备份工具,在服务可用性的前提下,更好地保证数据的完全性和安全性。

备份用户

为数据库中单独创建一个备份用户,只赋予所需尽可能少的权限。与应用帐号隔离开。不要为了偷懒而直接使用 root 用户!

1
2
3
4
5
6
7
8
-- 创建单独的备份用户
create user 'backup'@'localhost' Identified by '复杂密码';
-- 仅赋予备份用户对 db1 下数据的查询、视图以及锁表权限
grant select,LOCK TABLES,SHOW VIEW on db1.* to 'backup'@'localhost';
-- 备份使用的 Mysqldump 还需要 reload 权限
grant reload on *.* to 'backup'@'localhost';
-- 更新到数据库中
flush privileges;

执行计划

Linux 下可使用 crontab 设定执行计划。这可能是最简单的方式了。需要注意的是,这里是在独立的系统用户下设定的。

1
2
3
4
5
# 编辑当前用户的执行计划
crontab -e

# 从早上10点到晚上10点,每2小时备份一次。
0 10-22/2 * * * ~/scripts/mysql_backup.sh

参考脚本

在当前系统用户的Home目录下新建scripts目录,创建 mysql_backup.sh 文件,根据自己的环境设定相应参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/bin/bash

# 以下配置信息请自己修改
mysql_user="backup" # MySQL备份用户
mysql_password="backup_user_password" # MySQL备份用户的密码
mysql_host="mysql_server_ip"
mysql_port="mysql_server_port"
mysql_charset="utf8mb4" # MySQL编码
backup_dbs=("db1" "db2") # 要备份的数据库名称,多个用空格分开隔开 如("db1" "db2" "db3")
backup_location=/mnt/backup/mysql # 备份数据存放位置,末尾请不要带"/",此项可以保持默认,程序会自动创建文件夹
backup_log = $backup_location/mysql_backup.log
expire_backup_delete="ON" # 是否开启过期备份删除 ON为开启 OFF为关闭
expire_days=3 # 过期时间天数 默认为三天,此项只有在expire_backup_delete开启时有效

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

# 判断有没有定义备份的数据库,如果定义则开始备份,否则退出备份
if [ "$backup_dbs" == "" ];then
echo "ERROR:No database to backup! backup stop" >> $backup_log
exit
fi

# 判断MYSQL是否启动,mysql没有启动则备份退出
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!" >> $backup_log
exit
else
echo $welcome_msg >> $backup_log
fi

# 逐一对设定了的数据库进行备份
echo "Begining backup MySQL databases, please wait......" >> $backup_log
for dbname in ${backup_dbs[@]}
do
echo "database $dbname backup start..." >> $backup_log
`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" >> $backup_log
else
echo "database $dbname backup fail!" >> $backup_log
fi
done

# 如果开启了删除过期备份,则进行删除操作
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!" >> $backup_log
fi

echo "All database backup success! " >> $backup_log
exit