《用户数据备份方案》设计、开发、爬坑

最近公司要做一个数据备份,数据是用户产生的,基本上都是文件和图片。备份数据要打包成成 tar 包,所以设计如下方案:

《用户数据备份方案》
1. 采用 bash shell 开发数据备份脚本
2. 数据备份目录新建在 dcp/backup
3. 所有需要备份的文件打包为 tar 包,名字以年月日命名,如:2020-04-07.tar.gz 2020-04-07_all.tar.gz
4. 备份规则:
  • 天级:每天 00:00 备份昨天的产生的新数据

  • 周级:每周周一 00:00 备份所有的全量数据

5. 删除规则:
  • 每天 00:00 删除 7 天之前的天级备份数据

  • 每周周一 00:00 删除上周的周级备份数据

6. 定时执行:
  • 使用 crontab 执行定时任务

方案设计好以后就可以进行开发了。但是在开发的过程中遇到了不少小坑。

坑一:date 命令

由于我使用 Mac 进行开发的,所以在做时间处理的时候遇到了一些坑。 date 在进行时间加减的时候用的参数是 -d,但是在 Mac 下就报错了。这是因为在 Mac 下参数变成 -v

参考资料:
https://blog.csdn.net/weixin_37696997
https://www.cnblogs.com/alsodzy/p/8403870.html
https://blog.csdn.net/guddqs/article/details/80745464

为了兼容 Mac 和 Linux 发行版,我们需要判断当前系统是什么

#!/bin/bash

if [[ `uname -a` =~ "Darwin" ]]
then
    echo "Mac"

elif [[ `uname -a` =~ "centos" ]]
then
    echo "Centos"

elif [[ `uname -a` =~ "ubuntu" ]]
then
    echo "Ubuntu"

else
    echo "Other"
fi

~ 是判断右侧正则表达式是否匹配,匹配输出 1 不匹配输出 0

坑二: tar 包绝对路径

tar 打包是在相对路径下进行的

tar cvzf 2020_04-08_all.tar.gz files/

但是我们在写脚本为了路径正确,经常要用到绝对路径,如果直接使用有时会报错的,需要加上 P 参数,记得要放在 f 参数之前

tar cvzPf 2020_04-08_all.tar.gz /data/dcp/www/files/
坑三: tar 指定解压后的目录

如果直接用绝对路径打包,解压后包里面的目录是从根目录开始的,如果想指定文件的上级目录就需要加上 -C 参数来指定目录,然后指定解压后的目录是 files

tar cvzPf 2020_04-08_all.tar.gz -C /data/dcp/www files
坑四:findtar 配合使用

在打包的时候,有时候并不是所有的数据都要,这时候就需要过滤一部分数据进行打包,过滤查找就用 find 命令

find命令格式及find命令详解

find 按文件修改时间查找文件

findtar 配合使用有很多方式,具体参考下面的链接

How to find and tar files into a tar ball

这里我们使用最常见的管道命令

find /data/dcp/www/files -mtime 0 | xargs tar cvzf 2020_04-08.tar.gz

或者使用 -exec 命令

find /data/dcp/www/files -mtime 0 -exec tar cvzf 2020_04-08.tar.gz {} +
坑四:数据冗余

上述命令看似没有问题,但是在打包的时候回打包成多余的冗余数据,这是为什么呢?

原因是目录也有时间信息,如果要忽略目录只要文件,那么只需要加上 -type f 参数就好

find /data/dcp/www/files -type f -mtime 0 | xargs tar cvzf 2020_04-08.tar.gz
坑五:findtar 指定解压后的目录

使用 find 命令,打包需要管道,但是命令格式就会发生变化,为了指定目录,我们需要变通,换一种方式

cd /data/dcp/www
find files -mtime 0 | xargs tar cvzf 2020_04-08.tar.gz

这样就可以指定 findtar 解压后的目录

最后放出用户数据备份的源码:

#!/bin/bash

# today
dt=`date +"%Y-%m-%d"`

# src and dest file path
src="/data/dcp/www"
dest="/data/dcp/backup"

day() {
	find ${dest} -type f -name ${last_week}.tar.gz | xargs rm -rf
	cd $src
	find files -type f -mtime 0 | xargs tar cvzf ${dest}/${yesterday}.tar.gz 
}

week() {
	find ${dest} -type f -name ${last_week}_all.tar.gz | xargs rm -rf
	cd $src
	tar cvzf ${dest}/${dt}_all.tar.gz files/
}

# Judge Mac or Linux 
if [[ `uname -a` =~ "Darwin" ]]
then
	yesterday=`date -v -1d +"%Y-%m-%d"`
	last_week=`date -v -1w +"%Y-%m-%d"`
else
	yesterday=`date -d '-1 day' +%Y-%m-%d`
	last_week=`date -d '-1 week' +%Y-%m-%d`
fi

# day or week type
if [ "$1" = "day" ]
then
	day
elif [ "$1" = "week" ]
then
	week
else
	echo "--------- *Please input task type* ----------"
	echo "bash $0 day [OR] bash $0 week"
fi

最后,在 crontab 中添加定时任务

0 0 * * * bash /data/dcp/script/dcp_user_data_backup.sh day
0 0 * * 1 bash /data/dcp/script/dcp_user_data_backup.sh week

你可能感兴趣的:(#,Linux)