/var

2009年9月8日 星期二

Pahud's ZFS notes

這份文件是我用ZFS做備份的筆記,會持續補充,如果有任何意見歡迎email給我 pahudnet@gmail.com





產生incremental backup

zfs send -i old_vol newer_vol | gzip > incre.gz



根據incremental backup來恢復

gzip -d -c incre.gz | zfs recv mypool/o

* 注意,這個方式必須確保 mypool/o 目前資料等於old_vol狀態,否則會報錯



同上,強迫restore incremental backup之前先恢復到old_vol狀態, 多加一個-F即可

gzip -d -c incre.gz | zfs recv -F mypool/o

* 這個動作完成之後, mypool/o會restore到newer_vol狀態,同時會有一個該狀態的snapshot存在





混搭使用, 把本地的incremental backup丟到遠端,讓遠端保持最新狀態

zfs send -i yesterday_vol today_vol | gzip | ssh remote_host "gzip -d -c - | zfs recv -F mypool/o"



同上,如果在另一端的話

ssh orig_host "zfs send -i yesterday_vol today_vol | gzip" | gzip -d -c - | zfs recv -F mypool/o

* 這樣可以確保中間傳輸的資料流是gzip壓縮 



再延伸來看,假如127.0.0.1:6666有個tunnel到remote_host:22, 而orig_host在一個NAT底下,如果我要經常保持跟遠端ZFS一致,可以這樣處理



strtoday=$(date +%Y%m%d)    # 20090723

stryesterday=$(date --date=yesterday +%Y%m%d)   #20090722


ssh pahud@127.0.0.1 -p 6666 "sudo zfs send -i mypool/o@${stryesterday} mypool/o@${strtoday} | gzip " | \

gzip -d -c - | zfs recv -F mypool/o





要是希望再智能一點,可以寫個script, 定期去抓遠端最新的snapshot, 比對上次抓的,產生incremental backup, gzip壓縮傳回本地端之後再恢復,然後記錄下來最後這個snapshot name



# trigger remote_ssh

rm_ssh_exec() {

  ssh pahud@127.0.0.1 -p 6666 $1

}



# get latest snapshot name

get_latest_ss() {

  rm_ssh_exec "/usr/sbin/zfs list -r -t snapshot -o name rpool/o | tail -n 1"

}



# get previous snapshot name from local

get_local_last_ss() {

  cat /mypool/o/.last_sync_ss_from_remote

}



# begin the timer

f=$(date +%s)       

latest_ss=$(get_latest_ss)





rm_ssh_exec "sudo /usr/sbin/zfs send -i $(get_local_last_ss) $latest_ss | gzip " | \

gzip -d -c - | zfs recv -F mypool/o



if [ $? -eq 0 ]; then

  echo "lastest snapshot($latest_ss) restored to the local fs"

  sudo echo $latest_ss > /mypool/o/.last_sync_ss_from_remote

else

  echo "failed to restore lastest snapshot($latest_ss) to the local fs"

  exit 1

fi



# end the timer

t=$(date +%s)

s=$(( $t - $f ))

h=$(( $s / 60/60 ))

m=$(( ($s - $h*60*60) / 60 ))

s=$(( $s - $h*60*60 - $m*60))



echo "total: $h hour(s) $m min(s) $s sec(s)"





exit 0



測試完成!結果如下:



root@opensolaris:~/bin# sh getsnap.sh

lastest snapshot(rpool/o@20090724180000) restored to the local fs

total: 0 hour(s) 24 min(s) 12 sec(s)




追蹤者