《用戶數據備份方案》設計、開發、爬坑

最近公司要做一個數據備份,數據是用戶產生的,基本上都是文件和圖片。備份數據要打包成成 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章