SVN 备份恢复策略
2011-05-19 13:08
253 查看
SVN支持hotcopy和dump两种备份模式,hotcopy可以把整个代码库的目录结构拷贝出来包括配置文件和数据文件等,而dump以可读的方式将repository中的内容导出,支持增量备份。恢复hotcopy比较简单,直接将文件夹拷贝回原来的位置即可,恢复dump文件必须通过命令行的方式导入,如果某个增量备份丢失会导致恢复dump失败。
常见的备份策略是每天对dump进行增量备份,每周执行一次hotcopy备份。恢复的时候可以从dump恢复(时间较长),也可以先恢复hotcopy在从dump的增量恢复。
如果使用SVN edge server,用户信息和访问控制信息存放在csvn-production-hsqldb.properties和csvn-production-hsqldb.script中(data目录下),还有svn_access_file和svn_auth_file(data/conf目录下)。需要对这些文件分别备份。
SVN备份脚本:
SVN dump恢复脚本
常见的备份策略是每天对dump进行增量备份,每周执行一次hotcopy备份。恢复的时候可以从dump恢复(时间较长),也可以先恢复hotcopy在从dump的增量恢复。
如果使用SVN edge server,用户信息和访问控制信息存放在csvn-production-hsqldb.properties和csvn-production-hsqldb.script中(data目录下),还有svn_access_file和svn_auth_file(data/conf目录下)。需要对这些文件分别备份。
SVN备份脚本:
#!perl -w use File::Path qw(make_path); use File::Copy; use File::Compare; ####################################################### # # # main procedure # # # ####################################################### #log control flag my $DEBUG = 1; my $ERROR = 10; my $WARN = 8; my $INFO = 5; # current log level my $LEVEL = $DEBUG; if(@ARGV != 3){ &usage; exit 0 } #get arguments from command line my ($bk_type, $respo_dir, $backup_dir) = @ARGV; my @reopsitories; #bk_type = both or hotcopy or dump $bk_type = lc($bk_type); if($bk_type ne "both" && $bk_type ne "hotcopy" && $bk_type ne "dump"){ &error("Unknown backup type"); &usage; exit 1; } unless (-e $respo_dir){ &error("Unknown directocry $respo_dir"); exit 1; } unless (-e $backup_dir){ &error("Unknown directocry $backup_dir"); exit 1; } my %time = &format_date(localtime); &info("########## SVN server backup start ..."); opendir DH, $respo_dir or die "cannot open dir $respo_dir $!"; while(readdir DH){ next if $_ =~ /^/./; #skip dot files my $repo = "$respo_dir//$_"; next unless -e "$repo//format"; #skip any invalidate folder push @repositories, $_; } closedir DH; &debug("Discover repositories: ".join(", ", @repositories)); foreach (@repositories){ if($bk_type ne "both"){ if($bk_type eq "hotcopy"){ &hotcopy_repository($_); } if($bk_type eq "dump"){ &dump_repository($_); } } else { &hotcopy_repository($_); &dump_repository($_); } } &backup_cfg(); &info("########## SVN server backup complete ... "); ####################################################### # # # subroutines # # # ####################################################### sub hotcopy_repository{ unless(defined $_[0]){ &error("Repository is required!"); return; } my $repository = $_[0]; my $dumpfile_path = "$backup_dir//dump//$repository"; my $timelable = sprintf("%04d-%02d-%02d", $time{"year"}, $time{"month"}, $time{"day"}); my $repo_path = "$respo_dir//$repository"; my $hotcopy_path = "$backup_dir//hotcopy//${repository}//$timelable"; my $youngest = `svnlook youngest $repo_path`; my $last_update; chomp $youngest; if (! open HISTORY, "$dumpfile_path//backup_history"){ &info("backup_history for repository $repository does not exist, perform hotcopy anyway"); } else { chomp ($last_update = <HISTORY>); close HISTORY; } &debug("youngest : last_backup $youngest : $last_update"); if($last_update eq $youngest){ &info("No update to repository $repository"); return; } unless(-e $hotcopy_path){ if (! make_path($hotcopy_path)){ &error("Can not make dir $hotcopy_path, $!"); return; } &debug("Make dir $hotcopy_path sucessfully"); } my $command = "svnadmin hotcopy $repo_path $hotcopy_path 2>>$backup_dir//hotcopy//${repository}//${repository}_hotcopy.log"; &debug("Call svnadmin hotcopy to copy repository $repository starts."); &debug($command); my $rc = system($command); &debug("Hotcopy repository $repository ends, return value = $rc"); if($rc){ &error("Hotcopy repository $repository failed, please check ${repository}_hotcopy.log to find the root cause"); return; } #check zip is installed or in the environment variable #redirect the output to nul device $rc = system("7z > nul"); &debug("call 7z and get return code: $rc"); if($rc){ &warn("Zip utility may not be installed or configured correctly") } my $zipcmd = "7z a ${hotcopy_path}_$repository.7z $hotcopy_path"; &debug("Call zip command: $zipcmd"); &info("Compress the hotcopy to $hotcopy_path.7z"); system("7z a ${hotcopy_path}_$repository.7z $hotcopy_path > $hotcopy_path//..//zip.log"); &info("Hotcopy repository $repository successfully"); } #end of sub hotcopy_repository sub dump_repository{ my $repository = $_[0]; unless(defined $_[0]){ &error("Repository is required!"); return; } my $repo_path = "$respo_dir//$repository"; my $dumpfile_path = "$backup_dir//dump//$repository"; unless(-e $dumpfile_path){ if (! make_path($dumpfile_path)){ &error("Can not make dir $dumpfile_path, $!"); return; } } #Get the lastest revision my $youngest = `svnlook youngest $repo_path`; chomp $youngest; my $command; &debug("Latest revision of repository $repository $youngest"); if (!open FILE, "$dumpfile_path//backup_history"){ &info("backup_history for repository $repository does not exist, perform a full dump"); $command = "svnadmin dump $repo_path > $dumpfile_path//${repository}_full.dump 2>>$dumpfile_path//${repository}_dump.log"; } else { my $last_backup = <FILE>; chomp $last_backup; close FILE; &debug("Last backup revision of repository $repository $last_backup"); if($last_backup eq $youngest){ &info("No update to repository $repository"); return; } $last_backup += 1; &info("Incremental backup of repository $repository from revision $last_backup to $youngest"); $command = "svnadmin dump -r $last_backup:$youngest --incremental $repo_path > $dumpfile_path//${repository}_r$youngest.dump 2>>$dumpfile_path//${repository}_dump.log"; } &debug("Call svnadmin dump to dump repository $repository starts."); &debug($command); #the return code should be zero if command is successfully excuted my $rc = system($command); &debug("Dump repository $repository ends, return value = $rc"); if($rc){ &error("Dump repository $repository failed, check ${repository}_dump.log to find the root cause"); return; } &info("Dump repository $repository successfully"); #persist backup revision to file if(-e "$dumpfile_path//backup_history"){ copy("$dumpfile_path//backup_history", "$dumpfile_path//backup_history.bk"); } open FOUT, ">$dumpfile_path//backup_history" or die "Can not open file $dumpfile_path//backup_history $!"; print FOUT $youngest; close FOUT; }#end of sub dump_repository #subroutine backup svn_auth_file and svn_access_file under %csvnroot%/data/conf sub backup_cfg{ my $conf_source_dir = $respo_dir."//..//conf"; my $conf_backup_dir = $backup_dir."//conf"; unless(-e $conf_backup_dir){ if(! make_path($conf_backup_dir)){ &error("Can not make dir $conf_backup_dir $!, abort..."); return; } } #compare original and backup, backup if changes if(compare("$conf_source_dir//svn_auth_file", "$conf_backup_dir//avn_auth_file") != 0){ &info("Backup configuration file: svn_auth_file"); copy("$conf_source_dir//svn_auth_file", "$conf_backup_dir"); } if(compare("$conf_source_dir//svn_access_file", "$conf_backup_dir//svn_access_file") != 0){ &info("Backup configuration file: svn_access_file"); copy("$conf_source_dir//svn_access_file", "$conf_backup_dir"); } }#end of sub backup_cfg sub warn{ &_log($WARN, $_[0]); } sub debug{ &_log($DEBUG, $_[0]); } sub info{ &_log($INFO, $_[0]); } sub error{ &_log($ERROR, $_[0]); } # subroutine _log # usage: _log($level, $message); # sub _log{ my %d = &format_date(localtime()); my $level = $_[0]; my $lvldesc; if($level == $DEBUG){ $lvldesc = "DEBUG"; } elsif ($level == $INFO){ $lvldesc = "INFO"; } elsif ($level == $ERROR){ $lvldesc = "ERROR"; } elsif ($level == $WARN){ $lvldesc = "WARN"; }else { $lvldesc = "UNKOWN"; } my $message = sprintf("%04d-%02d-%02d %02d:%02d:%02d [%s] %s/n", $d{"year"}, $d{"month"}, $d{"day"}, $d{"hour"}, $d{"minute"}, $d{"second"}, $lvldesc, $_[1]); if($level >= $LEVEL){ print($message); &_wirte_file($message); } } sub _wirte_file(){ open LOG, ">>$backup_dir//backup.log" or die "failed to opne log file"; print LOG $_[0]; close LOG; } # subroutine format_date # # analyze output of localtime() and save the results to a hash # # usage: &format_date(localtime()); # sub format_date{ my ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = @_; my %d = ( "second" => $second < 10 ? "0".$second : $second, "minute" => $minute < 10 ? "0".$minute : $minute, "hour" => $hour < 10 ? "0".$hour : $hour, "day" => $dayOfMonth < 10 ? "".$dayOfMonth : $dayOfMonth, "month" => $month < 9 ? "0".$month + 1 : $month + 1, "year" => $yearOffset + 1900 ); return %d; } sub usage{ print "usage: perl $0 <backup_type> <repository_dir> <backup_dir>/n"; print "<backup_type> can be both, hotcopy or dump/n"; print "example: perl $0 hotcopy c://csvn//data//repositories d://svnbackup/n"; }
SVN dump恢复脚本
#!perl -w #restore dump files my $repo_dir = $ARGV[0]; my $dump_dir = $ARGV[1]; if(! @ARGV){ print "usage: perl $0 <repository dir> <dump dir>/n"; exit 0; } unless (-e $repo_dir){ print "Error unknown directocry $repo_dir $!"; exit 1; } unless (-e $dump_dir){ print "Error unknown directocry $dump_dir $!"; exit 1; } unless (-e "$repo_dir//format") { print "Error repository dir structure/n"; exit 1; } opendir DH, $dump_dir or die "cannot open dir $dump_dir $!"; my @dumps = grep { //.dump$/i && -f "$dump_dir/$_" } readdir(DH); closedir DH; my $cmd = "svnadmin load $repo_dir "; my $rc; foreach(@dumps){ $cmd .= "< $dump_dir//$_ >> svnresotre.log"; $rc = system($cmd); if($rc != 0){ print "Error during restore abort!"; return 1; } print "Successfully Load $dump_dir//$_/n"; }
相关文章推荐
- Oracle数据库文件恢复与备份策略
- linux svn服务器搭建、客户端操作、备份与恢复 推荐
- linux svn服务器搭建、客户端操作、备份与恢复
- svn备份策略
- hadoop主节点(NameNode)备份策略以及恢复方法
- hadoop主节点(NameNode)备份策略以及恢复方法
- MySQL 备份和恢复策略(二)
- MySQL 备份和恢复策略笔记(3)
- Linux下SVN服务器的安装与配置-备份-恢复-计划任务
- SVN服务器几种备份策略---重点svnsync备份---OK
- MySQL 备份和恢复策略(二)
- oracle 增量备份恢复策略(基础知识)
- svn 备份和恢复
- svn 备份和恢复
- Linux中SVN的备份与恢复
- SVN搭建(以此为准,成功)文后含备份与恢复
- svn库迁移-备份和恢复-svnadmin
- MySQL 备份和恢复策略笔记(4)
- ORACLE表空间的备份与恢复策略
- MySQL 备份和恢复策略(三)