作者:xuejiang
问题描述:
用svnadmin hotcopy备份的svn库是svn一个完整拷贝,保证了备份的完整、可靠。但用这种方式备份出现的问题是:备份占用空间比较大,需要定期进行删除,而我们发现删除非常困难。
尝试如下:
1、输入:rm -rf repos_backup1
提示访问拒绝。进到 repos/db/revs里面发现里面的文件权限都是
-r--r--r--
这样的,所以谁也不能用上面的命令进行删除了。
2、输入:rm -R repos_backup1
遇到每个文件都提示:是否重写权限,选择是,才会删除成功:
override rwxrwx--- 4294967294/users for 1117/repos1/db/revprops/11249?
一个库往往有数十个万个文件,这种删除方式显然不现实。
3、输入:chmod -R 777 repos_backup1;rm -R repos_backup1
等待半天,提示堆栈溢出。输入ulimit -a查看,堆栈限制为7715;修改这个参数必须重启系统,服务器级别比较高,不敢重启,只好作罢。
于是想到了用脚本来进行删除。
删除备份方案设计如下:
目标:定期删除备份数据,并保证备份数据一直介于7到16份之间
步骤:1、每月1号删除上个月21号之前所有数据
2、每月15号删除上个月所有数据和本月8号前的所有数据
3、每月25号删除本月19号之前的所有数据。
用perl脚本实现,代码如下:
#! /usr/bin/perl
# Author:xuejiang
# Site: http://www.scmbbs.com
#本单元:定期删除备份数据,并保证备份数据一直介于7到16份之间,
#适用:备份目录以mmdd的日期格式命名。
use Cwd;
use File::Find;
&main();
sub main()
{
#取得当前时间,根据时间设置定期进行删除
my $targetDir="/home/backup/svn/hotcopy2/"; #定义备份目录。
my( $sec, $min, $hour, $day, $month, $year,$wday,$yday ) = localtime( time() );
$month++;
my $today = sprintf( "%02d", $day);
if ($today !~ /(01$|15$|25$|)/)
{
exit(0);
}
my $monthday= sprintf( "%02d%02d", $month, $day);
my $thismonth= sprintf("%02d",$month);
my ($lastmonth,$passdate,$tempstr);
#定义删除的目录数组,对每个目录调用函数deleteDir进行删除。
chdir($targetDir);
my @dir=<*>;
print @dir;
if($thismonth=~/01/)
{
$lastmonth='12';
}else
{
$lastmonth=$thismonth - 1;
}
foreach my $dir(@dir)
{
if ($dir =~ /[^0-9]/)
{
next;
}
#每月1号删除上个月21号之前所有数据
if ($today=~/01$/)
{
$passdate=$lastmonth.'21';
if ($lastmonth == '12')
{
$tempstr= substr($dir,0,2);
if (($tempstr ne "01")&&($dir < $passdate))
{
&deleteDir($targetDir.$dir);
}
}else
{
if ($dir < $passdate)
{
&deleteDir($targetDir.$dir);
}
}
}
#每月15号删除上个月所有数据和本月8号前的所有数据
if ($today=~ /15$/)
{
$passdate=$thismonth.'08';
if ($dir < $passdate)
{
&deleteDir($targetDir.$dir);
}
if ($lastmonth == '12')
{
$tempstr= substr($dir,0,2);
if ($tempstr == "12")
{
&deleteDir($targetDir.$dir);
}
}
}
#每月25号删除本月19号之前的所有数据。
if ($today=~ /25$/)
{
$passdate=$thismonth.'19';
if ($dir < $passdate)
{
&deleteDir($targetDir.$dir);
}
if ($lastmonth == '12')
{
$tempstr= substr($dir,0,2);
if ($tempstr == "12")
{
&deleteDir($targetDir.$dir);
}
}
}
}
}
#递归遍历各目录,遍历各个文件,每个文件先进行chmod 777 filename操作,再进行 rm -rf filename操作。
sub deleteDir($)
{
my ($dir)=@_;
print "log in the dir:$dir /n";
my $handle;
opendir($handle,$dir);
while(defined(my $ndir=readdir($handle)))
{
if (($ndir eq ".")||($ndir eq ".."))
{
next;
}
$ndir=$dir."/".$ndir;
if (-f $ndir)
{
ls `chmod 777 $ndir`; ##如果需要此步。
print "file:$ndir/n" if unlink($ndir);
}else
{
print "Dir:$ndir/n";
deleteDir($ndir);
}
}
closedir($handle);
rmdir($dir);
print "now locate:$dir/n";
}