﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-放在手边-文章分类-web—others</title><link>http://www.blogjava.net/lan4020/category/40349.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 19 Jul 2009 17:28:47 GMT</lastBuildDate><pubDate>Sun, 19 Jul 2009 17:28:47 GMT</pubDate><ttl>60</ttl><item><title>Subversion备份</title><link>http://www.blogjava.net/lan4020/articles/287368.html</link><dc:creator>兰兰</dc:creator><author>兰兰</author><pubDate>Sun, 19 Jul 2009 12:38:00 GMT</pubDate><guid>http://www.blogjava.net/lan4020/articles/287368.html</guid><wfw:comment>http://www.blogjava.net/lan4020/comments/287368.html</wfw:comment><comments>http://www.blogjava.net/lan4020/articles/287368.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lan4020/comments/commentRss/287368.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lan4020/services/trackbacks/287368.html</trackback:ping><description><![CDATA[<span class="content"><strong>Subversion备份<br />
<br />
　</strong>版本控制最关键的一件事是保证数据的安全性，不能因为磁盘损坏，程序故障造成版本库无可挽回的错误，为此必须制定较完备的备份策略。在Subversion中，我们有三种备份方式：完全备份，增量备份和同步版本库。 </span>
<p class="content"><strong>1, 完全备份</strong><br />
<br />
　最常见和简单的备份就是直接使用拷贝命令，将版本库目录拷贝到备份目录上，就可以了。但是这样不是很安全的方式，因为如果在拷贝时版本库发生变化，将会造成备份的结果不够准确，失去备份的作用，为此Subversion提供了&#8220;svnadmin hotcopy&#8221;命令，可以防止这种问题。</p>
<p class="content">还记得我们的版本库目录吗？</p>
<table width="70%">
    <tbody>
        <tr>
            <td class="content" bgcolor="#cccccc">D:\SVNROOT<br />
            ├─project1<br />
            │ ├─conf<br />
            │ ├─dav<br />
            │ ├─db<br />
            │ │ ├─revprops<br />
            │ │ ├─revs<br />
            │ │ └─transactions<br />
            │ ├─hooks<br />
            │ └─locks<br />
            └─project2<br />
            ├─conf<br />
            ├─dav<br />
            ├─db<br />
            │ ├─revprops<br />
            │ ├─revs<br />
            │ └─transactions<br />
            ├─hooks<br />
            └─locks<br />
            </td>
        </tr>
    </tbody>
</table>
<p class="content">如果要把project1备份到d:\svnrootbak目录下，只需要运行：</p>
<p class="content">svnadmin hotcopy d:\svnroot\project1 d:\svnrootbak\project1</p>
<p class="content">但是我们作为配置管理员，必须想办法优化这个过程，如果我们这个目录下有许多版本库，需要为每个版本库写这样一条语句备份，为此我写了下面的脚本，实现备份一个目录下的所有版本库。我们在D:\SVNROOT下创建了两个文件，simpleBackup.bat：</p>
<p class="content">@echo 正在备份版本库%1......<br />
　@%SVN_HOME%\bin\svnadmin hotcopy %1 %BACKUP_DIRECTORY%\%2<br />
　@echo 版本库%1成功备份到了%2！</p>
<p class="content">这个文件仅仅是对&#8220;svnadmin hotcopy&#8221;的包装，然后是backup.bat：</p>
<p class="content">echo off</p>
<p class="content">rem Subversion的安装目录<br />
set SVN_HOME="D:\Subversion"</p>
<p class="content">rem 所有版本库的父目录<br />
set SVN_ROOT=D:\svnroot</p>
<p class="content">rem 备份的目录<br />
set BACKUP_SVN_ROOT=D:\svnrootbak</p>
<p class="content">set BACKUP_DIRECTORY=%BACKUP_SVN_ROOT%\%date:~0,10%<br />
if exist %BACKUP_DIRECTORY% goto checkBack<br />
echo 建立备份目录%BACKUP_DIRECTORY%&gt;&gt;%SVN_ROOT%/backup.log</p>
<p class="content">mkdir %BACKUP_DIRECTORY%</p>
<p class="content">rem 验证目录是否为版本库，如果是则取出名称备份<br />
for /r %SVN_ROOT% %%I in (.) do @if exist "%%I\conf\svnserve.conf" %SVN_ROOT%\simpleBackup.bat "%%~fI" %%~nI<br />
goto end</p>
<p class="content">:checkBack<br />
echo 备份目录%BACKUP_DIRECTORY%已经存在，请清空。<br />
goto end</p>
<p class="content">:end</p>
<p class="content">你在使用的时候，只需要修改backup.bat开头的三个路径，将两个脚本拷贝到&#8220;SVN_ROOT&#8221;下就可以了。根据以上的配置，你只需要运行backup.bat，就可以把&#8220;SVN_ROOT&#8221;下的版本库都备份到&#8220;BACKUP_SVN_ROOT&#8221;里，并且存放在备份所在日的目录里，例如&#8220;D:\svnrootbak\2006-10-22&#8221;。</p>
<p class="content">虽然这部分工作很简单，可是必须有人定时地去执行这个操作（例如每周一凌晨），为了避免发生遗忘的情况，我们可以将这个操作加入到系统的at任务当中去，例如还是上面的环境，为了安装at任务，我们运行：</p>
<p class="content">at 1:00 /every:M D:\svnroot\backup.bat这样在每周一凌晨1:00都会执行这个备份过程。当然备份在本机也是不安全的，你也许需要上传到别的机器，这个就要靠你自己去实现了。</p>
<p class="content"><strong>2, 增量备份</strong><br />
<br />
　尽管完全备份非常简单，但是也是有代价的，当版本库非常巨大时，经常进行完全备份是不现实的，也并不必要，但是一旦版本库在备份之间发生问题，该如何呢，这里我们就用到了增量备份。</p>
<p class="content">增量备份通常要与完全备份结合使用，就像oracle数据库的归档日志，记录着每次Subversion提交的变化，然后在需要恢复时能够回到最新的可用状态。在我们这个例子中我们使用的是，svnadmin dump命令进行增量的备份，使用方法是：</p>
<p class="content">svnadmin dump project1 --revision 15 --incremental &gt; dumpfile2</p>
<p class="content">上面的命令实现了对修订版本15进行增量的备份，其中的输出文件dumpfile2只保存了修订版本15更改的内容。</p>
<p class="content">为了记录每次提交的结果，我们需要使用一项Subversion的特性--钩子（hook），看看我们的project1目录：</p>
<table width="70%">
    <tbody>
        <tr>
            <td class="content" bgcolor="#cccccc">├─project1<br />
            │ ├─conf<br />
            │ ├─dav<br />
            │ ├─db<br />
            │ │ ├─revprops<br />
            │ │ ├─revs<br />
            │ │ └─transactions<br />
            │ ├─hooks<br />
            │ └─locks</td>
        </tr>
    </tbody>
</table>
<p class="content">其中的hooks目录里存放的就是钩子脚本，我们在此处只使用post-commit钩子，这个钩子会在每次提交之后执行，为了实现我们的备份功能，我们在hooks下建立一个文件post-commit.bat，内容如下：</p>
<table width="70%">
    <tbody>
        <tr>
            <td class="content" bgcolor="#cccccc">echo off<br />
            set SVN_HOME="C:\Program Files\Subversion"<br />
            set SVN_ROOT=D:\svnroot<br />
            set UNIX_SVN_ROOT=D:/svnroot<br />
            set DELTA_BACKUP_SVN_ROOT=D:\svnrootbak\delta<br />
            set LOG_FILE=%1\backup.log<br />
            echo backup revision %2 &gt;&gt; %LOG_FILE%<br />
            for /r %SVN_ROOT% %%I in (.) do if D:/svnroot/%%~nI == %1 %SVN_ROOT%\%%~nI\hooks\deltaBackup.bat %%~nI %2<br />
            goto end<br />
            :end</td>
        </tr>
    </tbody>
</table>
<p class="content">通过这个脚本，可以实现D:\svnroot下的版本库提交时自动增量备份到D:\svnrootbak\delta（确定这个目录存在），其中使用的deltaBackup.bat其实可以放在任何地方，只是对脚本的svnadmin dump的包装，内容如下：</p>
<p class="content">@echo 正在备份版本库%2......<br />
　%SVN_HOME%\bin\svnadmin dump %SVN_ROOT%\%1 --incremental --revision %2 &gt;&gt; %DELTA_BACKUP_SVN_ROOT%\%1.dump<br />
　@echo 版本库%2成功备份到了%3！</p>
<p class="content">以上两个脚本可以直接拷贝到project2的hooks目录下，不需要修改就可以实现project2的自动备份。</p>
<p class="content">以上的操作已经OK了，现在需要做的是将完全备份和增量备份结合起来，也就是在完全备份后清理增量备份的结果，使之只保存完全备份后的结果。</p>
<p class="content">当果真出现版本库的故障，就要求我们实现版本库的恢复操作了，这是用要使用svnadmin load命令，同时也需要上次的完全备份例如要把上次完全备份backuprepo，和之后的增量备份dumpfile：</p>
<p class="content">svnadmin load backuprepo &lt; dumpfile</p>
<p class="content">最后的结果，可以下载svnroot.rar，将之解压缩到d:\下，然后修改几个bat文件的SVN_HOME就可以使用了。</p>
<p class="content"><strong>3, 版本库同步</strong><br />
<br />
Subversion 1.4增加了同步机制，可以实现一个版本库同另一个版本库的同步（但好像只是单向的），我们可以用来实现版本库的备份或镜像。</p>
<p class="content"><strong>3.1. 对目标库初始化</strong><br />
<br />
　svnsync init svn://localhost/project2 svn://localhost/project1 <br />
　其中project2是目标的版本库，而project1是源版本库。其中的目标版本库必须为空，而且必须允许修订版本属性的修改，也就是在目标的版本库的hooks目录里添加一个文件pre-revprop-change.bat，内容为空即可。</p>
<p class="content"><strong>3.2. 同步project2到project1</strong><br />
<br />
　svnsync sync svn://localhost/project2 <br />
　这时候你update一下你的project2的一个工作拷贝，就会发现有了project1的所有内容。如果project1又有提交，这时候project2的版本库无法看到最新的变化，还需要再运行一遍sync操作，这样才能将最新的变化同步。需要注意的是，目标版本库只能做成只读的，如果目标版本库发生了变更，则无法继续同步了。</p>
<p class="content"><strong>3.3. 同步历史属性的修改</strong><br />
<br />
　因为同步不会更新对历史属性的修改，所以svnsync还有子命令copy-revprops，可以同步某个版本的属性。</p>
<p class="content"><strong>3.4. 钩子自动同步</strong><br />
<br />
　希望在每次提交时同步，则需要在源版本库增加post-commit脚本，内容如下：</p>
<table width="70%">
    <tbody>
        <tr>
            <td class="content" bgcolor="#cccccc">echo off<br />
            set SVN_HOME="D:\Subversion"<br />
            %SVN_HOME%\bin\svnsync sync --non-interactive svn://localhost/project2 </td>
        </tr>
    </tbody>
</table>
<p class="content">把以上内容存放为post-commit.bat，然后放到版本库project1下的hooks目录下，这样project1每次提交，都会引起project2的同步。<br />
<br />
参考网址：<a href="http://www.uml.org.cn/pzgl/200611151.htm">http://www.uml.org.cn/pzgl/200611151.htm</a> </p>
<img src ="http://www.blogjava.net/lan4020/aggbug/287368.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lan4020/" target="_blank">兰兰</a> 2009-07-19 20:38 <a href="http://www.blogjava.net/lan4020/articles/287368.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>subversion配置及权限管理</title><link>http://www.blogjava.net/lan4020/articles/287136.html</link><dc:creator>兰兰</dc:creator><author>兰兰</author><pubDate>Fri, 17 Jul 2009 05:31:00 GMT</pubDate><guid>http://www.blogjava.net/lan4020/articles/287136.html</guid><wfw:comment>http://www.blogjava.net/lan4020/comments/287136.html</wfw:comment><comments>http://www.blogjava.net/lan4020/articles/287136.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lan4020/comments/commentRss/287136.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lan4020/services/trackbacks/287136.html</trackback:ping><description><![CDATA[<p><strong>1、工具准备及安装：</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1)Subversion下载地址：<a href="http://subversion.tigris.org/">http://subversion.tigris.org</a> 其中setup-Subversion-1.6.31.msi为安装版本，svn-win32-1.6.3为绿色免安装版本。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Windows常用客户端TortoiseSVN下载地址：<a href="http://tortoisesvn.net/downloads">http://tortoisesvn.net/downloads</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2)安装subversion和tortoiseSVN<br />
默认安装即可。<br />
<br />
<strong>2、安装svnservice</strong><br />
　&nbsp;&nbsp;&nbsp; 以前的svnserve要想成为windows服务，必须依赖于svnservice或其他工具。从Subversion1.4开始，Subversion本身就集成Windows服务的工具。<br />
　&nbsp;&nbsp;&nbsp; 在Windows NT中（包括Windows XP, Windows 2000, Windows 2003 Server）本身包含了一个安装服务的工具，叫做"Service Control"，也就是sc.exe。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例如我的Subversion安装在"D:"Subversion"，版本库（资源文件存放的总目录）在"D:"svnroot"，而我希望对应的Subversion服务名为svnservice，安装这个svn服务的命令就可以这样写：</p>
<fieldset>sc create svnservice binpath= "D:"Subversion"bin"svnserve.exe --service -r D:"svnroot" displayname= "SVNService" depend= Tcpip</fieldset>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在命令行窗口执行完这个命令之后，服务还没有启动，你可以继续运行"net start svnservice"启动这个服务，然后使用"net stop svnservice"停止服务。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注意：另外还有两点需要小心处理。首先，如果路径中包括空格，一定要用&#8220;"&#8221;处理&#8220;"&#8221;号，例如上面的例子中如果svnserve.exe在&#8220;c:"program files"subversion"&#8221;中，则命令应该写为&#8220;binpath= """c:"program files"subversion"bin"svnserve.exe""&#8221;（&#8220;&#8221;中的内容），整个命令如下：</p>
<fieldset>sc create svnservice binpath= """D:"program files"Subversion"bin"svnserve.exe"" --service -r D:"svnroot" displayname= "SVNService" depend= Tcpip <br />
</fieldset>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其次，sc对选项的格式还有要求，例如&#8220;depend= Tcpip&#8221;不能写为&#8220;depend = Tcpip&#8221;或&#8220;depend=Tcpip&#8221;，也就是&#8220;=&#8221;前不能有空各，而后面必须有空格。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除服务<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果服务安装的有问题，你可能需要删除服务。要删除前面添加的服务，只需要运行"net start svnservice"，"svnservice"就是我们创建服务时使用的名字。<br />
<br />
<strong>3、创建资源库</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 方法一：多资源库：打开命令提示符，输入svnadmin create D:"svnroot " project1，回车；输入svnadmin create D:"svnroot " project2，回车...<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 方法二：安装好tortoiseSVN后，可以选中资源文件夹，如project1，右键，选择tortoiseSVN---create repository here即可。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 资源库目录如下：<br />
<br />
D:"SVNROOT<br />
├─project1<br />
│ ├─conf<br />
│ ├─dav<br />
│ ├─db<br />
│ │ ├─revprops<br />
│ │ ├─revs<br />
│ │ └─transactions<br />
│ ├─hooks<br />
│ └─locks<br />
└─project2<br />
├─conf<br />
├─dav<br />
├─db<br />
│ ├─revprops<br />
│ ├─revs<br />
│ └─transactions<br />
├─hooks<br />
└─locks<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>导入资源</strong>(可选操作)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例如将F:"resources下资源导入到project1中，在resources目录上右键，选择tortoiseSVN&gt;import，之后选择D:"SVNROOT即可。<br />
<br />
<strong>4、Subversion的权限控制</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D:"SVNROOT下有两个目录project1和project2，都已经创建了版本库，所以我们修改每个conf目录下的svnserve.conf，使之指向同一个password-db和authz-db文件。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; password-db = ..".."passwd<br />
　&nbsp;&nbsp;&nbsp; authz-db = ..".."authz<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这样，D:"SVNROOT"passwd和D:"SVNROOT"authz就控制了所有版本库的svnserve访问。将任一个conf目录下的passwd和authz文件拷贝到SVNROOT目录下。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 另外在后面的操作中要关闭匿名访问，应该去掉&#8220;anon-access = none&#8221;前的&#8220;#&#8221;号，保证只有认证用户可以访问。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注意：还有一点需要注意，那就是svnserve的&#8220;realm&#8221;的值，在上面的设置下，应该保证所有的版本库使用相同的realm值，这样，对版本库的密码缓存可以在多个版本库之间共享，更多细节见客户端凭证缓存。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 配置用户和组说明：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 假设project2目录下仍有目录111和222目录<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root：配置管理管理员，对版本库有完全的管理权限<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; project1_a:对project1有完全权限<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; project1_b:同上<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; project1_c:同上<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; project2_a:对project2有完全权限<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; project2_b:对project2文件夹下的111目录只有读权限，对222目录没有权限<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 修改D:"SVNROOT"passwd文件<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 前面已经说过了，用户和密码文件应该是在D:"SVNROOT"passwd，所以我们为每一位用户设置权限，文件内容如下：<br />
</p>
<fieldset>[users]<br />
project1_a = project1_a<br />
project1_b = project1_b<br />
project1_c = project1_c<br />
project2_a = project2_a<br />
project2_b = project2_b</fieldset>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 即为每一个用户设置用户名和密码，左侧为用户名，右侧为密码（为方便，密码同用户名）。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>配置授权<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>修改D:"SVNROOT"authz<br />
[groups]<br />
# 定义组信息,左侧为组名，右侧为改组成员的用户名<br />
group_project1 = project1_a, project1_b, project1_c<br />
group_ project2_a = project2_a<br />
group_ project2_b = project2_b<br />
[/]<br />
<br />
# 指定所有的版本库默认只读，root可读写<br />
* = r<br />
root = rw<br />
[project1:/]<br />
# 指定对版本库project1根目录的权限<br />
@ group_project1 = rw<br />
[project2:/]<br />
# 指定对版本库project2根目录的权限<br />
@ group_ project2_a = rw<br />
[project2:/111]<br />
# 指定对版本库project1的/111根目录的权限<br />
@ group_ project2_b = r<br />
[project2:/222]<br />
# 指定对版本库project1的/222根目录的权限<br />
@ group_ project2_b =<br />
<br />
<br />
（注：当没有权限时，该用户将看不到次目录）<br />
<br />
<strong>5、使用tortoiseSVN客户端工具访问</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在某一个目录下右键SVN Checkout即可,路径为svn://127.0.0.1/ project1,确定后输入用户名和密码<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 参考网址：http://www.uml.org.cn/pzgl/200611151.htm<br />
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/lan4020/aggbug/287136.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lan4020/" target="_blank">兰兰</a> 2009-07-17 13:31 <a href="http://www.blogjava.net/lan4020/articles/287136.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>