2009年12月17日 星期四

利用 cron 與 rsync 備份資料

Reference:
鳥哥的私房菜 - 例行性工作排程rsync manualA turial on using rsyncrsync exampletar - exclude files

上次電腦當機後,決心要幫電腦資料做定期備份,才不會一次打破整籃雞蛋,我的構想是每天晚上利用 rsync 備份更動最頻繁的 home 到另一顆硬碟上,每周五利用 tar 將不見時會搥心肝的重要資料打包成 gz 存到另一顆硬碟,再燒到光碟上,並存入隨身碟,總共存放在三處,如此一來,資料消失在世界上的風險性相信可以大大降低。

不過存放備份的硬碟是 fat 格式,造成 rsync 時沒辦法複製權限和一堆有的沒的東東而錯誤,卡在那邊花了不少時間,後來就隨它去了,不能設權限也沒差,反正資料在就好,而且用 tar 打包時就可以保留檔案權限了,而 tar 時原本想用 bzip2 或 lzma 壓縮,但是所花的時間多到讓我受不了,乾脆用簡單的 gzip ,有壓總比沒壓好,下一步要把 anacron 搞懂,才不會因為有時電腦沒開而少了一次備份。

備份的 script 都是用 python 寫的,rsync 的 exclude 跟 tar 有點不太一樣,為了研究這個還花了不少時間, 不過有了範本後,下次要寫其他 script 應該可以更快上手。
rsync script:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# use 'rsync' to backup files to a fat partition
# write logs into log_file

import time
import sys
import subprocess as sp

# not configure ACL, xattrs currently(can use -AX to sync)
# the same as -va --compress -stats --delete
# args = " --verbose --archive --compress --stats --delete "

# because sync file from ext3 to vfat lead to errors (vfat don't have
# some file attributes), need to remove some args
args = " --verbose --recursive --times --compress --delete "

# need to sync some windows program, so use exclude
# instead of --cvs-exclude
ex_PATTERN = [ "*~", "*.pyc",\
"**cache**","**Cache**","**CACHE**", "**.macromedia/",\
"**.opera/icons/", "**.thumbnails/"]

exclude = ''.join( map( lambda p: " --exclude=" + p, ex_PATTERN))

SRC = " /home/myHome"
DEST = " /mnt/HardDisk/back/sync"
# there is also --log-file=FILE option
log_file = "/home/mylog.log"

def write_log( messages ):
with open(log_file, 'a') as f:
f.writelines("\n***************************************\n")
f.writelines( time.ctime() )
f.writelines("\n***************************************\n")
f.writelines( messages )

try:
ret = sp.Popen(["rsync" + args + exclude + SRC + DEST],\
stdout=sp.PIPE,shell=True).communicate()[0]
write_log(ret)
except OSError, e:
write_log("Execution failed:" + e )





tar script:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# use 'tar' to backup files, save them as my_tar_Year_Month_Day.tar.gz
# write logs into log_file

import time
import sys
import subprocess as sp

# use -f in front of DEST to prevent args mix up
args = " -czv --exclude-caches-all"

SRC = " /mnt/HardDisk/my_precious \
/mnt/HardDisk/rotl "

TIME_STRING = time.strftime( "%Y_%m_%d", time.localtime() )

DEST = " /mnt/HardDisk/bak/mytar_" + TIME_STRING + ".tar.gz"

log_file = "/home/mytargz.log"

ex_PATTERN = [ "*~", "*.pyc",\
"**cache**", "**Cache**","**CACHE**",\
"**.macromedia/", "**.opera/icons/", "**.thumbnails/"]

exclude = ''.join( map( lambda p: " --exclude=" + p, ex_PATTERN))


def write_log( messages ):
with open(log_file, 'a') as f:
f.writelines("\n***************************************\n")
f.writelines( time.ctime() )
f.writelines("\n***************************************\n")
f.writelines( messages )

try:
# use -f in front of DEST to prevent args mix up
ret = sp.Popen(["tar" + args + exclude + " -f " + DEST + SRC ],\
stdout=sp.PIPE,shell=True).communicate()[0]
write_log(ret)
except OSError, e:
write_log("Execution failed:" + e )

沒有留言: