当前位置: > Linux服务器 > SVN >

Svn备份与恢复

时间:2014-11-27 14:29来源:linux.it.net.cn 作者:IT

 今天的主要任务是对svn的备份与恢复进行测试,但是测试的过程中,也出现的一些问题,现在写出来与大家进行分享,希望对大家有所帮助。

这里我介绍两种备份方式:完全备份和增量备份。

首先进行完全备份的测试,我从网上查的方法进行测试。

1. 完全备份

        最常见和简单的备份就是直接使用拷贝命令,将版本库目录拷贝到备份目录上,就可以了。但是这样不是很安全的方式,因为如果在拷贝时版本库发生变化,将会造成备份的结果不够准确,失去备份的作用,为此Subversion提供了“svnadmin hotcopy”命令,可以防止这种问题。

版本库目录结构如下图所示:

 

D:\svnroot
├─project1
│ ├─conf
│ ├─dav
│ ├─db
│ │ ├─revprops
│ │ ├─revs
│ │ └─transactions
│ ├─hooks
│ └─locks
└─project2
├─conf
├─dav
├─db
│ ├─revprops
│ ├─revs
│ └─transactions
├─hooks
└─locks

 

如果要把project1备份到d:\svnrootbak目录下,只需要运行:

svnadmin hotcopy d:\svnroot\project1 d:\svnrootbak\project1

但是如果我们这个目录下有许多版本库,则需要为每个版本库写这样一条语句备份,为此我写了下面的脚本,实现备份一个目录下的所有版本库。

我们在D:\svnroot下创建了两个文件,

simpleBackup.bat:

 

@echo 正在备份版本库%1......

@%SVN_HOME%\bin\svnadmin hotcopy %1 %BACKUP_DIRECTORY%\%2

@echo 版本库%1成功备份到了%2!

 

这个文件仅仅是对“svnadmin hotcopy”的包装,然后是

backup.bat:

 

@echo off

set SVN_HOME="C:\Program Files\VisualSVN Server"//VisualSVN Server的安装路径

set SVN_ROOT="D:\svnroot"//库根目录地址

set BACKUP_SVN_ROOT="D:\svnrootbak"//要备份的地址

set BACKUP_DIRECTORY=%BACKUP_SVN_ROOT%\%date:~0,10%

if exist %BACKUP_DIRECTORY% goto checkBack

echo %BACKUP_DIRECTORY%>>%SVN_ROOT%/backup.log

mkdir %BACKUP_DIRECTORY%

for /r %SVN_ROOT% %%I in (.) do @if exist "%%I\conf\svnserve.conf" %SVN_ROOT%\simplebackup.bat "%%~fI" %%~nI

goto end

:checkBack

@echo %BACKUP_DIRECTORY%

goto end

:end

 

你在使用的时候,只需要修改backup.bat开头的三个路径,根据以上的配置,你只需要运行backup.bat,就可以把“SVN_ROOT”下的版本库都备份到“BACKUP_SVN_ROOT”里,并且存放在备份所在的目录里,例如“D:\svnrootbak\2006-10-22”。

虽然这部分工作很简单,可是必须有人定时地去执行这个操作(例如每周一凌晨),为了避免发生遗忘的情况,我们可以将这个操作加入到系统的at任务当中去,例如还是上面的环境,为了安装at任务,我们运行:

at 11:30/every:F D:\svnroot\backup.bat这样在每周五晚上11:30都会执行这个备份过程。当然备份在本机也是不安全的,你也许需要上传到别的机器,这个就要靠你自己去实现了。

出现的问题:

  1. D:\svnrootbak\2006-10-22中是空的。

首先查看脚本,看看是不是路径写错了,经检查路径正确。然后运行命令,svnadmin hotcopy d:\svnroot\project1 d:\svnrootbak\project1发现命令不能运行,上网查原来是没设环境变量。

下面是设环境变量的步骤:右键我的电脑-属性,在系统属性对话框中选择“高级”,单击”环境变量”,然后编辑path路径,加上C:\Program Files\VisualSVN Server\bin;因为svn的命令都包含在这个文件夹下。

解决办法:加上路径后,运行正确。

2.增量备份

        尽管完全备份非常简单,但是也是有代价的,当版本库非常巨大时,经常进行完全备份是不现实的,也并不必要,但是一旦版本库在备份之间发生问题,该如何呢,这里我们就用到了增量备份。

增量备份通常要与完全备份结合使用,就像oracle数据库的归档日志,记录着每次Subversion提交的变化,然后在需要恢复时能够回到最新的可用状态。在我们这个例子中我们使用的是,svnadmin dump命令进行增量的备份,使用方法是:

svnadmin dump project1 --revision 15 --incremental > dumpfile2

其中project1处要写其所在具体的地址,如D:\svn_bak,dumpfile2处要写增量备份的文件夹地址,如D:\svnrootbak\svn.dump.

上面的命令实现了对修订版本15进行增量的备份,其中的输出文件dumpfile2只保存了修订版本15更改的内容。

为了记录每次提交的结果,我们需要使用一项Subversion的特性--钩子(hook),看看我们的project1目录:

 

├─project1
│ ├─conf
│ ├─dav
│ ├─db
│ │ ├─revprops
│ │ ├─revs
│ │ └─transactions
│ ├─hooks
│ └─locks

 

         其中的hooks目录里存放的就是钩子脚本,我们在此处只使用post-commit钩子,这个钩子会在每次提交之后执行,为了实现我们的备份功能,我们在hooks下建立一个文件post-commit.bat,内容如下:

 

@echo off

set SVN_HOME=C:\Program Files\VisualSVN Server//VisualSVN Server的安装路径

set SVN_ROOT=D:\svnroot//库根目录的地址

set DELTA_BACKUP_SVN_ROOT=D:\svnrootbak//要复制的地址

set LOG_FILE=D:\svnbackup.log//生成log文件的地址

echo backup revision %2 >> %LOG_FILE%

for /r %SVN_ROOT% %%I in (.) do if %SVN_ROOT%\%%~nI == %1 "%SVN_HOME%\bin\svnadmin" dump %1 --incremental --revision %2 >> %DELTA_BACKUP_SVN_ROOT%\%%~nI.dump

goto end

:end

 

通过这个脚本,可以实现D:\svnroot下的版本库提交时自动增量备份到D:\svnrootbak(确定这个目录存在),使用的时候只需要修改post-commit.bat开头的三个路径,其他的不需要修改就可以实现project2的自动备份。

以上的操作已经OK了,现在需要做的是将完全备份和增量备份结合起来,也就是在完全备份后清理增量备份的结果,使之只保存完全备份后的结果。

出现的问题:由于刚开始没搞懂钩子脚本是怎么回事,直接运行的post-commit.bat,结果连备份文件都没出现,因为钩子脚本是自动运行的。

解决办法:在版本库上进行添加或删除操作,结果正确。

3.备份恢复检查

当果真出现版本库的故障,就要求我们实现版本库的恢复操作了,这是用要使用svnadmin load命令,同时也需要上次的完全备份例如要把上次完全备份svn_bak,和之后的增量备份dumpfile:

svnadmin load  svn_bak的全路径< dumpfile增量备份的全路径

例如:svnadmin load E:\svn_bak< D:\svnrootback\svn.dump

对于已经备份好的版本库,可以通过乌龟访问到这个版本库的文件,例如:

出现的问题:当运行命令的时候,应该出来提示,而我测试出来的是空白,检查一下命令格式是否正确。经检查原来路径写错了,而且还少了个空格。

解决方法:改正确后,运行正确,出来提示信息。

以上是我进行svn备份与恢复的心得和体会,希望大家也有更多的资料拿来分享,咱们共同进步,在不断摸索中前进,加油!

(责任编辑:IT)
------分隔线----------------------------