backup脚本
基于rsync同步
实现功能:
- 全局备份,对于一个或多个目录文件进行打包压缩发送至存储路径
- 项目备份,对于单独项目内里的多个目录文件打包压缩至存储路径,支持增量备份
变量解释
start_time=`date +%s` #开始时间戳,用于计算程序运行时间
day=`date +%d` #日
month=`date +%m` #月
year=`date +%Y` #年
date=`date +%Y-%m-%d_%H-%M-%S` #当前时间
source /etc/profile #source一下环境变量
back_source_path=$source_paths #需要备份的地址,支持多个,以空格隔开。以环境变量方式读取
default_source_path=/data #如果没有配置备份地址,使用默认路径
project=$project_name #备份的项目名称
default_project=full #默认的项目名称
back_dest_path=$dest_path #备份目标地址
default_dest_path=/backup/ #默认备份目录
check_time=30 #定时检查项目文件更新,单位分
Delimiter="###" #分隔符
脚本存储路径规则
如果$dest_path没赋值采用默认备份存储目录$defautl_dest_path
全局备份规则
$dest_path/full/$year/$month/$year/$project-$date.tar.gz
项目备份规则
#项目全局备份存储路径
$dest_path/project/$project/full/$year/$month/$year/$project-$date.tar.gz
#项目增量备份存储路径
$dest_path/project/$project/latest/
执行示例
#设置脚本需要的环境变量
export source_paths="/etc/my.cnf.d###/var/lib/mysql" #这里以$Delimiter(脚本中默认为###)做分隔符,定义需要备份的路径
export project_name="mysql" #定义项目名,此环境变量只针对项目备份时才有用
全局备份
bash backup.sh full
#将需要备份的目录文件打包,并发送至存储地址/full/year/month/day/
项目备份
bash backup.sh project (fullbackup|increment)
#fullbackup 项目全局备份 会将需要备份的目录文件打包,并发送至项目数据存储地址/full
#increment 增量备份 会将需要备份的目录通过rsync同步到数据存储地址/latest
脚本内容
#!/bin/bash
start_time=`date +%s` #开始时间戳
day=`date +%d` #日
month=`date +%m` #月
year=`date +%Y` #年
date=`date +%Y-%m-%d_%H-%M-%S`
source /etc/profile
back_source_path=$source_paths #需要备份的地址,支持多个,依照分隔符隔开
default_source_path=/data #如果没有配置备份地址,使用默认路径
project=$project_name #备份的项目名称
default_project=full
back_dest_path=$dest_path #备份目标地址
default_dest_path=/backup/
Delimiter="###" #分隔符
project_backup(){
# $1 需要备份的路径
# $2 备份存储路径
# $3 备份方式(fullback: 全备,increment: 增量)
back_sources=`echo $1|sed "s/$Delimiter/ /g"`
back_path=$2
back_method=$3
#检测给定的路径是否存在
for source_path in $back_sources
do
if [ -e $source_path ];then
continue
else
echo "$source_path不存在,请检查备份路径"
return 1
fi
done
#备份方式
case $back_method in
#全备
"fullbackup")
full_backup "$back_sources" $back_path/full/$year/$month/$day $project
;;
#增量备份
"increment")
if [ ! -d $back_path/latest ];then
mkdir -p $back_path/latest
fi
for path in $back_sources
do
#如果路径是目录,并且存储上没有源路径,则先在存储路径创建一个路径
if [ -d $path ];then
mkdir -p $back_path/latest/$path
rsync -azlD $path/* $back_path/latest/$path
if [ $? -ne 0 ];then
echo "$path 未同步成功"
fi
#如果不是目录,则获取其所在目录,在存储路径创建其目录
else
file_name=`echo "$path" |awk -F '/' '{print $NF}'` #文件名
dir=`echo "$path" |sed "s/$file_name//g"` #所在目录
if [ ! -d $back_path/latest/$dir ];then #判断源目录是否存在
mkdir -p $back_path/latest/$dir
fi
rsync -azlD $path $back_path/latest/$dir
fi
if [ $? -ne 0 ];then
echo "$path 未同步成功"
fi
done
return 0
;;
esac
}
full_backup(){
# $1 需要备份的路径
# $2 备份存储地址
# $3 项目名称
back_sources=`echo $1|sed "s/$Delimiter/ /g"`
back_path=$2
project=$3
#判断备份存储路径是否存在
if [ ! -d $back_path ];then
mkdir -p $back_path
fi
tar -zcPf /tmp/$project-$date.tar.gz $back_sources
if [ ! $? -eq 0 ];then
echo "本地打包失败"
return 1
fi
rsync -azlD /tmp/$project-$date.tar.gz $back_path
if [ ! $? -eq 0 ];then
echo "备份传输失败"
return 1
fi
echo "-----------开始校验----------"
check_backup /tmp/$project-$date.tar.gz $back_path/$project-$date.tar.gz
if [ $? -eq 0 ];then
return 0
else
echo "error: $back_path/$project-$date.tar.gz md5值不一致"
fi
}
check_backup(){
#$1 校验源地址
#$2 校验目标地址
s_tar_md5=`md5sum $1|awk '{print $1}'`
d_tar_md5=`md5sum $2|awk '{print $1}'`
echo "源md5值:$s_tar_md5"
echo "备份md5值:$d_tar_md5"
if [ $s_tar_md5 == $d_tar_md5 ];then
return 0
else
return 1
fi
}
main(){
#$1备份方式(project:项目备份,full:全局备份)
#$2指定项目备份方式(fullback: 全备,increment: 增量)
methods=$1
if [ -z $back_dest_path ];then
back_dest_path=$default_dest_path
if [ ! -d $default_dest_path ];then
echo "默认存储地址$default_dest_path不存在"
return 1
fi
fi
case $methods in
"project")
if [ -z "$back_source_path" ];then
echo "请设定备份源路径(环境变量名:source_paths)"
return 1
fi
if [ -z "$project" ];then
echo "请设定项目名(环境变量名:project_name)"
return 1
fi
if [ ! -d $back_dest_path/project/$project ];then
mkdir -p $back_dest_path/project/$project
fi
echo -e "项目名:$project\n项目备份地址:$back_source_path\n数据存储位置:$back_dest_path/project/$project"
project_backup "$back_source_path" $back_dest_path/project/$project $2
echo "$back_source_path"|sed "s/$Delimiter/ /g" >$back_dest_path/project/$project/backup_path.data
;;
"full")
if [ -z "$back_source_path" ];then
back_source_path=$default_source_path
fi
if [ -z "$project" ];then
project=$default_project
fi
echo -e "项目名:$project\n项目备份地址:$back_source_path\n数据存储位置:$back_dest_path/full/$year/$month/$day"
full_backup "$back_source_path" $back_dest_path/full/$year/$month/$day $project
;;
esac
}
main $1 $2