一 创建备份路径
cd /mysql-backup
mkdir back
cd back
二 创建日志文件
vi mysql-backlog.log
内容为空,保存
三 创建备份脚本
cpp
vi save-all-data.sh
#!/bin/bash
#source /etc/profile
user="root"
password="LXYlxy2:024.#8u}"
host="127.0.0.1"
port="3306"
db=("test" "test3" "test4" "test9") #数组表示要备份的数据库
local="--single-transaction"
mysql_path="/usr/local/mysql/bin/mysql" #Mysql命令路径
backup_path="/mysql-backup/data" #备份文件存储路径
date=$(date +%Y%m%d_%H%M%S) #备份文件添加时间戳
day=30 #定义保存备份天数
backup_log="/mysql-backup/back/mysql-backlog.log" #备份日志文件路径
if [ ! -e $backup_path ];
then
mkdir -p $backup_path
fi
find $backup_path -type f -mtime +$day -exec rm -rf {} \; > /dev/null 2>&1 #/dev/null为特殊设备,输入到该设备内容都会被丢弃,2>:将标准错误输出重定向,$1:标准错误输出到与标准输出相同的地方,结合:将命令的标准输出和标准错误输出都丢弃,不会显示到屏幕和记录到文件中。
echo "开始备份数据库: ${db[*]}"
#使用循环遍历db数组中所有的数据库,调用自定义backup_sql函数备份
backup_sql(){
dbname=$1 #将函数backup_sql的第一个参数赋值给dbname,即为以下的length
backup_name="${dbname}_${date}.sql"
#--flush-logs:备份前刷新二进制日志,-R:备份时要包括存储过程和函数,保证还原数据完整
/usr/local/mysql/bin/mysqldump -h $host -P $port -u $user -p$password --default-character-set=utf8 --socket=/data/mysql/tmp/mysqld.sock --flush-logs -R $dbname > $backup_path/$backup_name
if [[ $? == 0 ]]; #$?获取上一个命令退出状态,0为成功,非0为失败
then
cd $backup_path
tar -czvf $backup_name.tar.gz $backup_name --force-local #只访问本地文件,本地压缩
size=$(du $backup_name.tar.gz -sh | awk '{print $1}')
rm -rf $backup_name
echo "$date 备份 $dbname($size) 成功"
else
cd $backup_path
rm -rf $backup_name
echo "$date 备份 $dbname 失败"
fi
}
#先自定义函数,在调用,这里for循环次数由数据库个数决定,backup_sql第一个传递参数$length
length=${#db[@]} #@获取整个数组的元素,#为获取数据长度,结合起来:返回db中元素个数
for ((i=0;i<$length;i++));do
backup_sql ${db[i]} >> $backup_log 2>&1
done
echo "备份结束,结果查看 $backup_log"
du $backup_path/*$date* -sh | awk '{print "文件:" $2 ",大小:" $1}' #使用swk切割管道符前命令的第一和二字段
四 脚本赋权,linux自带定时任务工具配置
chmod +x save-all-data.sh
crontab用法:
crontab -e 编辑工作表
crontab -l 列出工作表中的命令
crontab -r 删除工作表
HELL=/bin/bash
00 01 * * * /mysql-backup/back/save-all-data.sh
sed -i 's/\r//g' 命令可以格式化sh文件,用法为:sed -i 's/\r//g' xxx.sh
save-all-data.sh 指定12:20和01:00定时间点执行,数据库异地备份
:wq保存文件即可
五 脚本改进:1.按天数区分备份数据2.自动遍历需要备份的数据库
以下为改良1
cpp
#!/bin/bash
#source /etc/profile
user="root"
password="LXYlxy2:024.#8u}"
host="127.0.0.1"
port="3306"
db=("test" "test3" "test4" "test9") #数组表示要备份的数据库
local="--single-transaction"
mysql_path="/usr/local/mysql/bin/mysql" #Mysql命令路径
backup_path="/mysql-backup/data" #备份文件存储路径
date=$(date +%Y%m%d_%H%M%S) #备份文件添加时间戳
day=30 #定义保存备份天数
backup_log="/mysql-backup/back/mysql-backlog.log" #备份日志文件路径
#if [ ! -e $backup_path ];
# then
# mkdir -p $backup_path
#fi
#############改进1:区分每一天的备份文件######################
current_date=$(date +%Y%m%d) # 获取当前日期
daily_backup_path="$backup_path/$current_date" # 每天备份目录
#只需要将后续使用到$backup_path替换成daily_backup_path,上面的可注释掉
if [ ! -e $daily_backup_path ]; then
mkdir -p $daily_backup_path
fi
##############################################################
find $backup_path -type f -mtime +$day -exec rm -rf {} \; > /dev/null 2>&1 #/dev/null为特殊设备,输入到该设备内容都会被丢弃,2>:将标准错误输出重定向,$1:标准错误输出到与标准输出相同的地方,结合:将命令的标准输出和标准错误输出都丢弃,不会显示到屏幕和记录到文件中。
echo "开始备份数据库: ${db[*]}"
#使用循环遍历db数组中所有的数据库,调用自定义backup_sql函数备份
backup_sql(){
dbname=$1 #将函数backup_sql的第一个参数赋值给dbname,即为以下的length
backup_name="${dbname}_${date}.sql"
#--flush-logs:备份前刷新二进制日志,-R:备份时要包括存储过程和函数,保证还原数据完整
/usr/local/mysql/bin/mysqldump -h $host -P $port -u $user -p$password --default-character-set=utf8 --socket=/data/mysql/tmp/mysqld.sock --flush-logs -R $dbname > $daily_backup_path/$backup_name
if [[ $? == 0 ]]; #$?获取上一个命令退出状态,0为成功,非0为失败
then
cd $daily_backup_path
tar -czvf ${backup_name}.tar.gz $backup_name --force-local #只访问本地文件,本地压缩
echo " $?" #调试:tar命令执行成功,但是一直没有.tar.gz包
size=$(du ${backup_name}.tar.gz -sh | awk '{print $1}')
rm -rf $backup_name
echo "$date 备份 $dbname($size) 成功"
else
cd $daily_backup_name
rm -rf $backup_name
echo "$date 备份 $dbname 失败"
fi
}
#先自定义函数,在调用,这里for循环次数由数据库个数决定,backup_sql第一个传递参数$length
length=${#db[@]} #@获取整个数组的元素,#为获取数据长度,结合起来:返回db中元素个数
for ((i=0;i<$length;i++));do
backup_sql ${db[i]} >> $backup_log 2>&1
done
echo "备份结束,结果查看 $backup_log"
du -sh $daily_backup_path/*${date}* | awk '{print "文件:" $2 ",大小:" $1}' #使用swk切割管道符前命令的第一和二字段
改良2:
cpp
#!/bin/bash
#source /etc/profile
user="root"
password="LXYlxy2:024.#8u}"
host="127.0.0.1" #要给root权限,host三种设置:1.localhost:本地主机连接(默认) 2.%:所有主机 3.固定IP,这里要给root的host权限设置为2或3,否则下面使用-h 选项会报错
port="3307"
#db=("test" "test3" "test4" "test9") #数组表示要备份的数据库
#db=($($mysql_path -h $host -P $port -u $user -p$password -e "SHOW DATABASES;" | grep -Ev "Database|information_schema|performance_schema|sys"))
#db放在这里,执行的时候会一直报错为找-h -p -u命令,这是因为脚本是按顺序下来执行
local="--single-transaction"
mysql_path="/usr/local/mysql/bin/mysql" #Mysql命令路径
#db=($($mysql_path -h $host -P $port -u $user -p$password -e "SHOW DATABASES;" | grep -Ev "information_schema|performance_schema|sys"))
#标准输出提示mysql[warning],2>/dev/null 来将标准错误输出重定向到 /dev/null,从而将这个警告信息忽略
#db=($($mysql_path -h $host -P $port -u $user -p$password -e "SHOW DATABASES;" 2>/dev/null | grep -Ev "information_schema|performance_schema|sys"))
#shell脚本中,使用$(命令)来执行命令返回结果,和`命令`效果一样--在shell脚本中,数组存储方式:1.括号赋值 数组=(),2.逐个赋值a[0]="12"3.通过命令的输出来赋值 4.使用declare声明关联数组
db=(`$mysql_path -h $host -P $port -u $user -p$password -e "SHOW DATABASES;" 2>/dev/null | grep -Ev "information_schema|performance_schema|sys"`)
backup_path="/mysql-backup/data" #备份文件存储路径
date=$(date +%Y%m%d_%H%M%S) #备份文件添加时间戳
day=30 #定义保存备份天数
backup_log="/mysql-backup/back/mysql-backlog.log" #备份日志文件路径
#if [ ! -e $backup_path ];
# then
# mkdir -p $backup_path
#fi
#############改进1:区分每一天的备份文件######################
current_date=$(date +%Y%m%d) # 获取当前日期
daily_backup_path="$backup_path/$current_date" # 每天备份目录
#只需要将后续使用到$backup_path替换成daily_backup_path,上面的可注释掉
if [ ! -e $daily_backup_path ]; then
mkdir -p $daily_backup_path
fi
##############################################################
find $backup_path -type f -mtime +$day -exec rm -rf {} \; > /dev/null 2>&1 #/dev/null为特殊设备,输入到该设备内容都会被丢弃,2>:将标准错误输出重定向,$1:标准错误输出到与标准输出相同的地方,结合:将命令的标准输出和标准错误输出都丢弃,不会显示到屏幕和记录到文件中。
echo "开始备份数据库: ${db[*]}"
#使用循环遍历db数组中所有的数据库,调用自定义backup_sql函数备份
backup_sql(){
dbname=$1 #将函数backup_sql的第一个参数赋值给dbname,即为以下的length
backup_name="${dbname}_${date}.sql"
#--flush-logs:备份前刷新二进制日志,-R:备份时要包括存储过程和函数,保证还原数据完整
/usr/local/mysql/bin/mysqldump -h $host -P $port -u $user -p$password --default-character-set=utf8 --socket=/data/mysql/tmp/mysqld.sock --flush-logs -R $dbname > $daily_backup_path/$backup_name
if [[ $? == 0 ]]; #$?获取上一个命令退出状态,0为成功,非0为失败
then
cd $daily_backup_path
tar -czvf ${backup_name}.tar.gz $backup_name --force-local #只访问本地文件,本地压缩
echo " $?" #调试:tar命令执行成功,但是一直没有.tar.gz包
size=$(du ${backup_name}.tar.gz -sh | awk '{print $1}')
rm -rf $backup_name
echo "$date 备份 $dbname($size) 成功"
else
cd $daily_backup_name
rm -rf $backup_name
echo "$date 备份 $dbname 失败"
fi
}
#先自定义函数,在调用,这里for循环次数由数据库个数决定,backup_sql第一个传递参数$length
length=${#db[@]} #@获取整个数组的元素,#为获取数据长度,结合起来:返回db中元素个数
for ((i=0;i<$length;i++));do
backup_sql ${db[i]} >> $backup_log 2>&1
done
echo "备份结束,结果查看 $backup_log"
du -sh $daily_backup_path/*${date}* | awk '{print "文件:" $2 ",大小:" $1}' #使用swk切割管道符前命令的第一和二字段
参考 优秀文档