SVN备份方案策略
<h4>SVN实时备份方案</h4>
<p><code>总体备份策略说明</code></p>
<p>本地备份及异机备份均采用官方推荐的比较安全的备份方式svnadmin hotcopy进行增量备份,效率高,安全,且恢复效率快。</p>
<blockquote>
<p>1、通过SVN-hook脚本<code>post-commit</code>脚本在用户提交完成后自动触发<code>svnadmin hotcopy</code>热备份操作进行增量同步,可定义3个同步源,同时对同步源有效性进行检测,当某个同步源同步失败触发邮件通知到管理员检查同步源,并对同步结果做日志记录,使用此方法可同时统计用户的提交频率。
2、定义钩子管理脚本及版本号校验脚本(每30分钟执行一次),包含如下功能:自动对svn父目录下所有svn仓库创建自动同步钩子脚本,同时钩子管理脚本运行时自动比对所有备份服务器SVN版本号,若存在版本号不一致则对版本号不一致得版本库执行一次针对该库的热备份操作,同时邮件通知管理员。</p>
</blockquote>
<p><code>SVN仓库验证方案</code></p>
<blockquote>
<p>1、每周对SVN父目录及备份仓库父目录下所有SVN仓库使用<code>svnadmin verify</code>对仓库进行完整性校验;
2、为保证备份效率,多个仓库父目录每天只验证一个,轮换进行校验,同时采用<code>8-10</code>个多线程并发校验,提高校验效率;
3、校验记录会进行日志记录,同时记录<code>日期,时间,仓库名,版本号,验证状态</code>信息,同时校验失败的仓库路径信息会通过邮件通知到配置管理员;</p>
</blockquote>
<hr />
<h4>一、先安装sshfs并挂载备份服务器备份目录至主机</h4>
<p>参照如下教程:
<a href="https://www.showdoc.cc/vNote?page_id=2825037002729489">https://www.showdoc.cc/vNote?page_id=2825037002729489</a></p>
<p><strong>1、在主机安装sshfs客户端,备份服务器无需安装</strong></p>
<pre><code>yum -y install fuse-sshfs sshfs</code></pre>
<p><strong>2、创建ssh密钥,直接按3次回车即可</strong></p>
<pre><code>#如已存在密钥则跳过此步,切勿覆盖旧的密钥,以免造成其他影响
ssh-keygen</code></pre>
<p><strong>3、在主机上传密钥至备份服务器,输入一次备份服务器密码即可</strong></p>
<pre><code>ssh-copy-id -i ~/.ssh/id_rsa.pub '-p 22 root@172.16.2.150'</code></pre>
<p><strong>4、测试主机登录备份服务器,无需密码</strong></p>
<pre><code>ssh root@172.16.2.150</code></pre>
<p><strong>5、挂载远端ssh指定目录</strong></p>
<pre><code>mkdir /mnt/150
/usr/bin/sshfs -o nonempty,allow_other,exec,reconnect root@172.16.2.150:/home/codebackup/svn /mnt/150</code></pre>
<p><strong>6、主机配置开机自动挂载备份机备份目录</strong></p>
<pre><code>crontab -e
@reboot (umount /mnt/109;/usr/bin/sshfs -o nonempty,allow_other,exec,reconnect root@192.168.0.109:/backups/svn /mnt/109)
@reboot (umount /mnt/150;/usr/bin/sshfs -o nonempty,allow_other,exec,reconnect root@172.16.2.150:/home/codebackup/svn /mnt/150)</code></pre>
<hr />
<h4>二、crontab邮件通知配置</h4>
<pre><code>#安装mailx
yum install mailx -y
#编辑邮箱配置文件
vim /etc/mail.rc
#在最后加入如下内容:
set from=pax-svn@paxsz.com
set smtp=mail.paxsz.com
#若邮箱支持匿名验证仅需配置如上部分即可,若不支持匿名验证则需要填写如下配置信息
set smtp-auth-user=huangwj
set smtp-auth-password=xxxxxxx
set smtp-auth=login
#在crontab中配置收件人
crontab -e
#在文件首行加入收件人邮箱
MAILTO=huangwj@paxsz.com</code></pre>
<hr />
<h4>三、热备份脚本配置</h4>
<h1>配置执行计划,每半个小时执行一次</h1>
<pre><code>crontab -e
#每30分钟执行一次钩子管理脚本
*/30 * * * * /bin/bash /root/SvnHookManage.sh
#开机自动挂载SVN远程备份路径
@reboot (umount /mnt/109;/usr/bin/sshfs -o nonempty,allow_other,exec,reconnect root@192.168.0.109:/backups/svn /mnt/109)
@reboot (umount /mnt/150;/usr/bin/sshfs -o nonempty,allow_other,exec,reconnect root@172.16.2.150:/home/codebackup/svn /mnt/150)</code></pre>
<p><strong>如下脚本包含如下功能:</strong></p>
<ul>
<li>检测备份路径有效性,若备份路径不存在则通过邮件提醒到配置管理员;</li>
<li>热备份hook管理,每30分钟间隔执行一次hook检查,自动为所有库及新曾SVN仓库创建热备份hook<code>post-commit</code>;</li>
<li>当管理脚本中的hook更新后,批量对比热备份hook,当备份hook不一致时,批量更新不一致的hook;</li>
<li>当svn仓库提交成功后,自动对提交的仓库增量热备份至多个备份路径;</li>
<li>日志记录功能,热备份完成后进行日志记录,可记录每一次提交的(日期,时间,仓库名,版本号,修改人,备份路径,状态),可通过excel打开进行筛选分细相关数据。</li>
</ul>
<pre><code class="language-shell">#!/bin/bash
#SVN实时备份钩子创建脚本
HookLogFile=/var/log/SvnHotBak.log
#定义SVN父目录
SvnRoot=/data/svnroot
#定义多个备份路径,可指定本地或者挂载的sshfs目录,至少填写一个备份路径,不够则留空
BackupDest1=/mnt/109/svnroot
BackupDest2=/mnt/150/svnroot
BackupDest3=/backups/DataHotCopy/svnroot
SVN_BACKUP_LIST="$BackupDest1 $BackupDest2 $BackupDest3"
#备份路径有效性校验
for BD in $SVN_BACKUP_LIST
do
[ -e $BD ]||echo 备份路径:[ $BD ]异常,路径不存在,请检查备份路径.
done
#日志格式:日期,时间,仓库名,版本号,修改人,状态
#生效钩子文件:repo/hooks/post-commit
hook(){
cat > $1 << EOF
#!/bin/sh
#SVN热备份同步钩子,请勿删除及手动修改
#如需修改请在该文件修改:$0
REPOS="\$1"
REV="\$2"
TXN_NAME="\$3"
#定义SVN备份目录列表
SVN_BACKUP_LIST="$BackupDest1 $BackupDest2 $BackupDest3"
#定义日志备份文件路径
SVN_BACK_LOG=$HookLogFile
log(){
df -kh \$3 | grep : >/dev/null&&Dest=\`df -kh \$3 | grep :\`||Dest=\$3
echo \`date '+%Y-%m-%d,%H:%M'\`,\`basename \$1\`,\$2,\`svnlook author \$1 -r \$2\`,\$Dest,\$4 >> \$SVN_BACK_LOG
}
for SVN_BACKUP in \$SVN_BACKUP_LIST
do
[ -e \$SVN_BACKUP ]&&(
flock -w 7200 \$REPOS/conf/authz -c "svnadmin hotcopy --incremental \$REPOS \$SVN_BACKUP/\${REPOS##*/}" &&(
log \$REPOS \$REV \$SVN_BACKUP Succeess
)||(
log \$REPOS \$REV \$SVN_BACKUP Fail
)
)
done
EOF
}
#输出临时hooks用于对比,避免hook反复写入硬盘
hook `dirname $HookLogFile`/post-commit
[ -e $HookLogFile ]||(touch $HookLogFile&&chmod 777 $HookLogFile&&chown csvn $HookLogFile)
for repo in `ls $SvnRoot`
do
[ -e $SvnRoot/$repo/conf/authz ] && (
diff `dirname $HookLogFile`/post-commit $SvnRoot/$repo/hooks/post-commit ||hook $SvnRoot/$repo/hooks/post-commit
chmod +x $SvnRoot/$repo/hooks/post-commit
)
done</code></pre>
<hr />
<h4>四、备份校验脚本配置</h4>
<pre><code>crontab -e
#每天晚上1点运行备份校验脚本
00 01 * * * /bin/bash /root/svnshell/repo_verify.sh</code></pre>
<p><strong>如下脚本包含如下功能:</strong></p>
<ul>
<li>每日进行主服务器与备份路径SVN版本号对比,如果不一致则执行增量热备份并邮件通知配置管理员,作为补充保证热备份版本一致性,同时对备份仓库配置文件进行对比同步;</li>
<li>每7个工作日进行版本库完整性校验<code>svnadmin verify</code>,同时进行校验日志记录,若校验不通过则邮件通知到配置管理员</li>
<li>
</li>
<li>
</li>
<li>
</li>
</ul>
<pre><code class="language-shell">#!/bin/bash
#SVN仓库及备份仓库完整性校验脚本
#定义多个备份库路径
SvnRoot=/data/svnroot
SvnBak1=/backups/DataHotCopy/svnroot
SvnBak2=/mnt/109/svnroot
SvnBak3=/mnt/150/svnroot
LogFile=/data/svn_verify.csv
Check_List="$SvnRoot $SvnBak1 $SvnBak2 $SvnBak3"
Conf="authz passwd svnserve.conf"
#SVN主仓库与备份版本库版本号比对及版本号不一致时执行热备份,每日执行一次,不做日志记录,仅在异常时进行邮件通知,同时对比SVN仓库conf目录配置文件进行对比并同步
Bak_List="$SvnBak1 $SvnBak2 $SvnBak3"
for Dest in $Bak_List
do
for repo in `ls $SvnRoot`
do
[ -e $SvnRoot/$repo/conf/authz ]&&(
[ $(svnlook youngest $SvnRoot/$repo) != $(svnlook youngest $Dest/$repo) ]&&(
svnadmin hotcopy --incremental $SvnRoot/$repo $Dest/$repo&&(
echo $Dest/$repo:版本号不一致,已执行热备份--`svnlook youngest $SvnRoot/$repo`
)
)
for cf in $Conf
do
diff $SvnRoot/$repo/conf/$cf $Dest/$repo/conf/$cf >/dev/null||cp -f $SvnRoot/$repo/conf/$cf $Dest/$repo/conf/$cf
done
)
done
done
#版本号有效性校验,每7天执行一次,每天检测一个备份路径(根据每年366天天数除以7取余进行判断)
everyone=`expr $(date +%j) % 4`
init=0
#日志格式:日期,时间,仓库名,版本号,状态
log() {
echo `date '+%Y-%m-%d,%H:%M'`,$1,`svnlook youngest $SvnRoot/$1`,$2 >> $LogFile
}
verify() {
SvnRoot=$1
for repo in `ls $SvnRoot`
do
[ -e $SvnRoot/$repo/conf/authz ] && (
svnadmin verify $SvnRoot/$repo 2>/dev/null&&(
log $repo "$SvnRoot/$repo,Successfull"
)||(
log $repo "$SvnRoot/$repo,Fail"
echo `date '+%Y-%m-%d,%H:%M'`,$SvnRoot/$repo,版本库校验失败,请及时检查.
)
)
done
}
for ck in $Check_List
do
if [ $init == $everyone ];then
[ -e $ck ]&&verify $ck||echo 备份路径:$ck 不存在,无法进行版本库校验,请检查备份路径.
fi
init=`expr $init + 1`
done
#csvn授权文件备份脚本
/bin/bash /data/svnconf/svn_ae_bak.sh</code></pre>