Acronis True Image の増分バックアップを回転
Windowsマシンの自動バックアップ用に、Acronis True Image Home 11 を買ってみた。(True Image 9は前から使ってたけど)
True ImageはHDDパーティションやファイルの増分バックアップ(差分バックアップ)が取れるバックアップソフト。
バックアップローケーションという機能があって、古いバックアップファイルを自動的に消してくれる。しかし、古いファイルを消すときにかなり時間がかかるっぽい…。完全バックアップと増分バックアップをマージしているみたいで、これに時間がかかってるのかな。
というわけで、バックアップローケーション機能を使うのはあきらめて、増分バックアップ前に、バックアップファイル数が一定数に達したら自動的に別ディレクトリへバックアップファイルを移動(古い世代から順次削除)するRubyスクリプトを作ってみた。
完全バックアップファイルが無い状態で増分バックアップをかけると、完全バックアップを取ってくれるみたいなので、これで完全+増分バックアップを一定世代数保存できる。
バックアップ開始時に、"trueimage_rotate.bat D:\backup_dir MyBackup 2 4" のようなコマンドを実行させる。この例の場合、D:\backup_dir\MyBackup*.tib の数を数えて、増分バックアップが4つ以上になったら、別ディレクトリへ移動(最大2世代まで保存)する。
trueimage_rotate.bat
ruby trueimage_rotate.rb %* > %1\trueimage_rotate.log 2>&1
trueimage_rotate.rb
#!ruby -Ks # TrueImageの増分バックアップが一定数に達したら、別ディレクトリへ移動 # 古いディレクトリは削除 if ARGV.length<4 puts "Usage: #{$0} (バックアップディレクトリ) (バックアップファイル名(連番,拡張子無し)) (完全バックアップ保持数) (増分バックアップ保持数)" exit 1 end def error(msg) STDERR.puts(msg) exit 1 end backdir=ARGV[0] basename=ARGV[1] maxbasenum=ARGV[2].to_i maxznum=ARGV[3].to_i $olddirbase='_old_'+basename+'_' error("not dir: #{backdir}") if !FileTest.directory?(backdir) error("maxbasenum<1") if maxbasenum<1 regexp_files=Regexp.new('^'+Regexp.escape(basename)+'(\d*)\.tib$',Regexp::IGNORECASE) hasbase=false znum=0 backfiles=[] Dir.foreach(backdir) do |file| if regexp_files =~ file # backup files zindex=$~[1].to_i puts "file: #{file},#{zindex}\n" if zindex<=1 hasbase=true else znum+=1 end backfiles << file end end puts "znum:#{znum}" exit unless hasbase && znum>=maxznum # rotate! puts "rotate!" #Umm $backdir=backdir $maxbasenum=maxbasenum $regexp_files=regexp_files $regexp_tib=/\.tib$/i def olddirname(index) $backdir+"/"+$olddirbase+index.to_s end # index番目のolddirを後ろにずらして空にする def rotate(index) dir=olddirname(index) if FileTest.directory?(dir) if index>=$maxbasenum # delete oldest dir print "delete #{dir}\n" Dir.foreach(dir) do |file| File.delete(dir+"/"+file) if $regexp_tib =~ file end Dir.rmdir(dir) sleep(1) # 待たないと次の名前変更がPermission Errorになる??? elsif # rotate to next rotate(index+1) print "rename #{dir} to #{olddirname(index+1)}\n" File.rename(dir,olddirname(index+1)) sleep(0.1) # 念のため end end true end # 最新のものを移動 rotate(1) olddir=olddirname(1) error("olddir #{olddir} already exists")if FileTest.directory?(olddir) workdir=olddirname(0) Dir.mkdir(workdir) unless FileTest.directory?(workdir) Dir.foreach($backdir) do |file| File.rename($backdir+'/' + file, workdir +'/'+ file) if regexp_files =~ file end File.rename(workdir,olddir)
※ファイル削除処理等が含まれているので、万が一使いたい場合は、十分動作確認してからお願いします。
- -
追記:どうも、この方法で増分バックアップをとると、パスワードの設定や暗号化が無効になってしまうっぽい...。うむむ