如需转载,请注明出处:http://bbs.iusesvn.com/thread-3068-1-1.html
此文讲述SVN如何镜像服务器,注意是单向镜像。众所周知,SVN有自已的镜像命令svnsync(svn1.4以及以上版本特性),但是部署与维护确是繁琐至极,令人望而却步。我们来看一个简单的svnsync例子:
主SVN服务器: http://mastersvn/project1
svnsync镜像SVN服务器上的部署:http://backupsvn/project1
第一步:建立仓库
cd /home/svn
svnadmin create –fs-type fsfs /home/svn/project1
chmod 777 –R project1
第二步:镜像初始化
svnsync init http://backupsvn/project1 http://mastersvn/project1
第三步:更改配置文件
cd /home/svn/project1/hooks
cp pre-revprop-change.tmpl pre-revprop-change
vi pre-revprop-change
注销所有语句,在语句前加入#即可,退出保存
第四步:同步
svnsync sync http://backupsvn/project1 --username username --password password
已提交版本 9。
复制版本 9 的属性。
已提交版本 10。
复制版本 10 的属性
……………
但是在实际运用中,经常会发生SVN库被lock的情况
svnsync: Couldn't get lock on destination repos after 10 attempts
这不得不让我们感觉头痛地手动使用改命令解锁
svn propdel svn:sync-lock --revprop -r0 http://backupsvn/project1
写到这里,大家不由对svnsync有了个初步的认识了吧,就一个字,烦!!!而且同步速度很慢!!!
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
接下来是此文的重点部分:
SVN新的镜像备份方案:ssh + rsync + crontab(任务计划))
什么是SSH?
SSH 是更灵活、更安全的 telnet 和 rlogin 替代品。它在开发项目中得到广泛使用,以提供访问控制和安全的数据传输。
什么是rysnc?
rsync是类unix系统下的数据镜像备份工具,从软件的命名上就可以看出来了——remote sync。它的特性如下:
可以镜像保存整个目录树和文件系统。
可以很容易做到保持原来文件的权限、时间、软硬链接等等。
无须特殊权限即可安装。
优化的流程,文件传输效率高。
可以使用rcp、ssh等方式来传输文件,当然也可以通过直接的socket连接。
支持匿名传输,以方便进行网站镜象。
什么是crontab?
Crontab是Linux操作系统下的一个命令,可以用来根据时间、日期、月份、星期的组合来调度对重复任务的执行的守护进程。(类似windows下的任务计划)
方案拓扑图:(请看附件)
主SVN服务器环境:
SVN仓库根目录: /home/svn (project1,project2,project3三个仓库)
SVN服务器IP: 192.168.100.80
镜像SVN服务器环境:
SVN仓库根目录:/home/svn (无仓库,无需建立,镜像时会直接复制过来并保持文件属性)
SVN服务器IP: 192.168.100.81
#主SVN服务器安装部分:
(1)
SVN安装部分(略)
(2)
安装rsync部分
rpm -qa | grep rsync (所有系统是否有安装过rsync)
rpm -e rsyncxxx (删除以前安装过的rsync)
wget http://samba.anu.edu.au/ftp/rsync/rsync-3.0.4.tar.gz (下载rsync源码安装包)
tar zxvf rsync-3.0.4.tar.gz (解压)
cd rsync-3.0.4
./install.sh (安装)
接下来我们就可以输入rsync --version命令来测试下是否安装成功了。
rsync
version 3.0.3
protocol version 30
Copyright (C) 1996-2008 by Andrew Tridgell, Wayne Davison, and others.
Web site: http://rsync.samba.org/
Capabilities:
64-bit files, 64-bit inums, 32-bit timestamps, 64-bit long ints,
socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace,
append, ACLs, xattrs, iconv, no symtimes
rsync comes with ABSOLUTELY NO WARRANTY.
This is free software, and you
are welcome to redistribute it under certain conditions.
See the GNU
General Public Licence for details.
(3) 开启rsync服务器端
/usr/local/bin/rsync --daemon (开启rsync服务)
vi /etc/rc.d/rc.local
在末尾加入/usr/local/bin/rsync --daemon (目的是让服务器每次重启后都能自动运行此进程)
#镜像SVN服务器安装部分:
(1)SVN安装部分(略)
(2)安装rsync部分
rpm -qa | grep rsync (所有系统是否有安装过rsync)
rpm -e rsyncxxx (删除以前安装过的rsync)
wget http://samba.anu.edu.au/ftp/rsync/rsync-3.0.4.tar.gz (下载rsync源码安装包)
tar zxvf rsync-3.0.4.tar.gz (解压)
cd rsync-3.0.4
./install.sh (安装)
接下来我们就可以输入rsync --version命令来测试下是否安装成功了。
接下来我们的配置就完成了,让我们用命里那个测试下。
同步命令:
rsync -vzrtopgu --progress --delete root@192.168.100.80:/home/svn /home/
输入用户名root
输入root的密码。
65309 100%
224.57kB/s
0:00:00 (xfer#507, to-check=2187/23106)
svn/project1/db/revs/202
29655 100%
99.86kB/s
0:00:00 (xfer#508, to-check=2186/23106)
svn/project1/db/revs/203
7242 100%
23.19kB/s
0:00:00 (xfer#509, to-check=2185/23106)
sent 15928 bytes
received 521860019 bytes
4404016.43 bytes/sec
total size is 12240235825
speedup is 23.45
传输完成,这次镜像过程就结束了。
让我们看看所使用的参数:
v 复杂的输出信息
z 压缩模式, 当资料在传送到目的端进行档案压缩.
r 复制所有下面的资料(透过)
t 保留时间点
o 保留档案所有者(root only)
p保留档案权限
g 保留档案群组
u更新修改过的文件
--progress 显示传送的进度
--delete 删除传送断已经不存在,而目的端存在的档案
root@192.168.100.80:/home/svn /home/
用root用户访问192.168.100.80的/home/svn目录,然后同步到本机的/home/目录下,注意格式,那么镜像SVN服务器就会把主SVN服务器上的/home目录的svn文件夹整个复制到镜像SVN服务器上的/home下,并保存原属性不变。
###注意:为什么使用root的用户呢,因为可以确保保证同步过来的文件可以保证档案的具体属性,这是我们比较关心的问题,但是root的用户拥有的权限太大了,每次都需要输入root的密码,一方面这是非常危险的,一方面比较繁琐。
那么我们首先想到的不需要输入用户名和密码就可以镜像和传输文件,那么必须让两台SVN服务器互相信任,那么我们需要采用ssh私钥和公钥加密技术。
主SVN服务器:
ssh-keygen –d
Enter file in which to save the key (/home/root/.ssh/id_dsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/root/.ssh/id_dsa.Your public key has been saved in /home/root/.ssh/id_dsa.pub.The key fingerprint is:32:21:e1:3b:7d:6e:de:4b:39:da:af:38:fe:90:40:61 root@svnserver.com
cd .ssh
id_dsa ------------ 私钥文件
id_dsa.pub ------------ 公钥文件
cp id_dsa.pub authorized_keys2 (复制一个可以被root识别和读取的公钥文件)
chmod 600 authorized_keys2 (因安全因为给予600权限)
cp id_dsa.pub svnserver.pub (再做一份公钥的副本)
想办法把这个公钥的副本移动到镜像SVN服务器上面。
cat mirrorsvnserver.pub >> authorized_keys2 (把复制过来的镜像SVN服务器上的公钥导入到主SVN服务器的公钥文件里)
镜像SVN服务器:
ssh-keygen –d
Enter file in which to save the key (/home/root/.ssh/id_dsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/root/.ssh/id_dsa.Your public key has been saved in /home/root/.ssh/id_dsa.pub.The key fingerprint is:32:21:e1:3b:7d:6e:de:4b:39:da:af:38:fe:90:40:61 root@mirrorsvnserver.com
cd .ssh
id_dsa ------------ 私钥文件
id_dsa.pub ------------ 公钥文件
cp id_dsa.pub authorized_keys2 (复制一个可以被root识别和读取的公钥文件)
chmod 600 authorized_keys2 (因安全因为给予600权限)
cp id_dsa.pub mirrorsvnserver.pub (再做一份公钥的副本)
想办法把这个公钥的副本移动到主SVN服务器上面。
cat svnserver.pub >> authorized_keys2 (把复制过来的主SVN服务器上的公钥导入到镜像SVN服务器的公钥文件里)
让我们里验证公钥文件中的内容:
cat /root/.ssh/authorized_keys2
ssh-dss AAAAB3NzaC1kc3MAAACBAL9iAG+VZkXunZ5KzTivat1deDAQFKdrGY5P2rxRI+QeKClNgfukUNwQmU+a5FqfNsLKlWhGbIfFI1k00Zkc7nwMdG2dtcnWw7oUqPCGizMcoPLXXQhfOPaFoOkB5UPWNkgJobBPZBjJ7nhKZxzzMiujhOVYLvGNDEWI8x3NAAAAFQCqqtJaMgVyMgDexUKbHIBXsSghYIB5U82gTyGb2c4z4AsmQ5M0ds3YHHVLPHRUEn7DspzlNZ7fYWhKzQYWlhPJftuYTrYIEzuXx8Hl8kg7hCEl4hArAgMMcEtmuQ+3x5SkEht3077qUPdC/YzSk7cFNwQlt6nOeYELCIwhs1CXWQXi9E/XSlqepd+gSlAAhVzWc0MgAAAIAy4qWyaB6DT+XWtq23jrFrYeejJyFBVkNVUbEd3GNTHvwKTYuBa7nlh562g5r0riIrHW+a7WGd6U32RVLnqqIwddcHml4kXnondo0qjW4XijYI7jkHN9oAK5mNWnSCYAnot1nra3QXlh9472/l7kTmznumjsDDjAIa7OFY9w== root@svnserver.com
ssh-dss AAAAB3NzaC1kc3MAAACBAPI3YFCQNBof9xA/Fi1S0U4jmliAg/TaWHnx9suaYb5Xc31jW3+axbNURIBnK7cA53q+qBME1DdddSBOq+I0oUpfjAXkOUl/ACRbSRqA1VOaKdI2AOH9tw4jSK0xSqYjj+ReuUnuVMSTOJTQzt1n6YsLj/kjAAAAFQCHE5NqPCIlr5xVFYOZmGysI+CtKQAAAIAb/gjP0f3Ifx0H2A3XzH9fG4YENLd+gz0l07Mq356+IBuPSYxi4JldxZ7j1OkH9j+7+t8AOSyqNqiOzKXpimo0NLjVsEkpn9RXFmzfHHwRholmauDKIbGLvJlTL0ZkjqH3w0plGmVC6YyxOpM4w7XklIvtq3rDZQE4O247yxgAAAIEA2rd2htKfO9I7F+rBxVgszeGrwCfP5gf8sdz32LDd+E4JxzI/b79Tn1ylILb0vGZhRCbFhoLnDIUMR3Lrr5FqGlTf8O2gsvproA5pLqUpgrkhR/7siycplOddftt553yBJNCBkq+E906AwQ72PNs2uLrbKHyVyD1akrD2/hfA= root@svnmirrorserver.com
这样我们的两台SVN服务器就得到信任了。
让我们再次执行同步命令:
rsync -vzrtopgu --progress --delete root@192.168.100.80:/home/svn /home/
发现了什么?
已经不需要输入用户名和密码了。
最后我们需要设定人物计划了。
crontab –e
*/10 * * * * /usr/local/bin/rsync -vzrtopgu --progress --delete root@192.168.100.80:/home/svn /home/ &
退出保存。
这个例子是每10分钟同步一次,当然我们也可以设置我们想要的时间。
另外一个例子:每小时同步一次
* */1 * * * /usr/local/bin/rsync -vzrtopgu --progress --delete [email=root@192.168.100.80:/home/svn]root@192.168.100.80:/home/svn /home/ &
备注:
(1) 所有同步都为增量备份,笔者不建议大家都采用增量备份对SVN进行备份,这有可能导致SVN库日后不可用,但笔者这里将尽有不下50个SVN库,同步几月都没发生任何问题,都能正常被使用。但是为了谨慎起见,希望大家再做一个定期全备份,建议每周一次。如有用户因此丢失,笔者将不负任何责任。
(2) 此方法适应Windows上使用,rsync程序名称为cwRsync
(3) rsync有二种配置方式:一种是ssh,scp,stock等协议直接传输,无需修改配置文件(笔者用法),第二种是修改rsync配置文件,映射路径和指定密码(支持匿名)
(4) ssh + rsync + crontab只是复制文件而已,无需依赖apache和subversion程序
附件:
rsync 所以试用参数列表:
-h , --help 显示rsync
求助资讯
--version 顯示rsync版本
-v , --verbose 复杂的输出信息
-q , --quiet 安静模式,几乎没有讯息产生,
常用在以cron执行rsync
-I, --ignore-times 通常rsync为了加快速度会忽略同样档案大小且同样,同样存取时间点的档案
可以通过此参数开关此快速检查.
--size-only rsync
只检查档案大小是否改变,不管时间存取点是否改变
通常用在mirror, 且对方时间不太正确时
-c, --checksum 在传送之前透过128bit的md4检查码来检查所有要传送的档案(会托满速度);
-a, --archive archive mode 权限保存模式,相当于 -rlptgoD 参数.
很快速的保存几乎所有的权限设定,除了硬式连接(透过-H设定).
-r, --recursive 复制所有下面的资料(透过)
-R, --relative 使用相对路径
如: rsync foo/bar/foo.c remote:/tmp/ 在远端产生/tmp/foo.c档案
rsync -R foo/bar/foo.c remote:/tmp/ 在远端产生/tmp/foo/bar/foo.c 档案
-R, --relative 不使用相对路径
-b, --backup 目的地端先前已经存在的档案在传输或删除前会被备份
--backup-dir=DIR 设定备份的资料夹
--suffix=SUFFIX 指定备份的档案名称字尾形式(预设为~)
-K, --keep-dirlinks 接收方将连接到资料夹的档案视为资料夹处理
-l, --links 复制所有的连接
-H, --hard-links 保留硬式连结
-p, --perms 保留档案权限
-o, --owner 保留档案所有者(root only)
-g, --group 保留档案群组
-u –
update 更新修改过的文件
-D, --devices 保留device资讯(root only)
-t, --times 保留时间点
-n, --dry-run 不实际执行传送, 只显示将会有的传输动作
-S, --sparse 尝试去处理稀疏的档案, 让这些档案在目的端占去较少的磁碟空间
-W, --whole-file 复制所有的档案, 不额外作检查
--no-whole-file 关闭 --whole-file 参数
-x, --one-file-system 不要跨越档案系统分界(只在一个档案系统处理)
-B, --block-size=SIZE 强制透过rsync程式去比对修复block-sizeforce
-e --rsh=COMMAND 定义所试用的remote shell
--rsync-path=PATH 定义rsync在远端
机器存放资料的路径
--existing 只对比更新目的端已经存在的档案
--ignore-existing 忽略目的断已经存在的档案(也就是不更新)
--delete 删除传送断已经不存在,而目的端存在的档案
--delete-excluded 除了把传送端已经不存在, 而目的端存在的档案删除之外, 也删除 --exclude 参数所包含的档案
--delete-after rsync预设会在档案传送前进行相关删除动作确保接收端有足够的档案空间,
单可以透过 --delete-after 让删除动作在档案传送后在进行删除
--ignore-
errors 忽略任何错误即使是I/O error 也进行 --delete 删除动作
--max-delete=NUM 定义rsync不要删除超过NUM个档案
--partial rsync若遇到传输过程中断时, 会把那些已经传输的档案删除.
在某种状况下保留那些部分传送的档案是令人高兴的;
你可以透过 --partial 参数达到这个目的.
--partial-dir=DIR 在 --partial 参数启动时, 你还是可以定义rsync把那些部分传送的档案
写入定义的资料夹, 而非直接写入目的端,需要注意的是,
此资料夹不应该被其他试用者可以写入.(如:/tmp)
--force 当目的端资料夹被传送端非资料夹名称覆盖时, 强制rsync删除资料夹, 即使该资料夹不是空的.
--numeric-ids 不将传送端档案的uid及gid值, 与目的端的使用者/群组进行配对,
若传送端并没有uid及gid的对应名称(如:原帐号群组被删除的遗留档案),
或目的端没有相对应的帐号/群组, 保留数字型式的uid/gid
--timeout=TIMEOUT 设定I/O 超时的时间(秒). 超过这个秒数而没有资料传送, rsync将会结束. 预设为0,也就是没有定义超时时间
-T, --temp-dir=DIR 定义rsync在接收端产生暂时性的复制档案时使用资料夹暂存,
预设时直接在接收端资料夹直接产生暂存档案
--compare-dest=DIR 定义rsync在目的端建立资料夹来比对传送过来的档案.
--link-dest=DIR 与 --compare-dest 相同,但同时会针对无法改变的档案建立硬式连结.
-z, --compress 压缩模式, 当资料在传送到目的端进行档案压缩.
-P -P参数和 --partial --progress 相同.只是为了把参数简单化.
-C, --
cvs-exclude 排除那些通常不希望传送的档案, 定义的方式与CVS传送相同:
RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state
.nse_depinfo *~ #* .#* ,* _$* *$ *.old *.bak *.BAK *.orig *.rej
.del-* *.a *.olb *.o *.obj *.so *.
exe *.Z *.elc *.ln core .svn/
符合以上条件的都会被忽略不传送.
--exclude=PATTER 符合PATTERN(规则表示式)样式的档案不仅行传送
--exclude-from=FILE 和 --exclude 参数相同, 不过是把不进行传送的档案事先写入某一档案.
执行时, 透过此参数让rsync读取.
(; #开头的行列或者空白会被rsync忽略)
--include=PATTERN 定义rsync不要排除符合pattern样式的档案
--include-from=FILE 和--include参数相同,只不过把要包含的档案写到某一档案.
--files-from=FILE 把要传送的档案名称都精确的写入某一档案, 让rsync读取.
如: rsync -a --files-from=/tmp/foo /usr remote:/backup
-0 --from0 定义档案所要读取的档案时null字元结尾.
--version 现四版本信息.
--daemon 定义rsync以daemon型态执行
--no-detach 当以daemon形态执行时,不要进行分裂且变成背景程序.
--address=ADDRESS 定义所要连接(bind)的ip位置或者是host名称(daemon限定)
--
config=FILE 定义所要读取的设定档rsyncd.conf位置(daemon限定)
预设值为 /usr/local/etc/rsyncd.conf
--port=PORT 定义rsyncd(daemon)要旨行的port(预设为tcp 873)
--blocking-io 使用blocking I/O连结远端的shell, 如rsh, remsh
--no-blocking-io 使用non-blocking连结远端的shell, 如ssh(预设值)
--stats 显示档案传送时的资讯状态
--progress 显示传送的进度.(给档案传送时,怕无聊的人用的..)
--log-format=FORMAT 定义log的格式(在rsyncd.conf设定)
--password-file=FILE 从档案读取与远端rsync伺服务连结的密码
--bwlimit=KBPS 定义传输频宽的大小(KBytes/秒)
--write-batch=FILE 把记录资料写入一个档案(给其他相同环境且相同需求的机器试用)
--read-batch=FILE 透过读取记录档案来进行传输.(档案由 --write-batch 参数产生)
--checksum-seed=NUM 定义档案 checksum-seed 的大小(byte)
-4 --ipv4 使用IPv4协定
-6 --ipv6 使用IPv6协定