zoukankan      html  css  js  c++  java
  • Subversion的备份

    想给Subversion服务器做简单的自动备份,也不知道别人是怎么弄的,自己想了个笨办法。

    【环境】

    A机:Subversion服务器,IP为192.168.1.16  B机:备份机器,IP为192.168.1.66

    【策略】

    每周六晚上23:30点进行hotcopy全量备份,每天晚上23:30点进行dump的增量备份。增量备份只是备份了从上次备份版本库到现在的变化。恢复的时候可以从dump恢复(时间较长),也可以先恢复hotcopy再从dump的增量恢复。

    【思路】

    将B的home目录mount在A上,这样A往自己的/mnt目录里备份,实际就备份在了B的/home里。当然之前需要测试是否连接。

    【原理】

    Subversion支持hotcopy和dump两种备份模式。hotcopy可以把整个代码库的目录结构拷贝出来,包括配置文件和数据文件等;而dump以可读的方式将repository中的内容导出,支持增量备份。恢复hotcopy比较简单,直接将文件夹拷贝回原来的位置即可,恢复dump文件必须通过命令行的方式导入,如果某个增量备份丢失会导致恢复dump失败。

    svnadmin hotcopy是将整个库都“热”拷贝一份出来,包括库的钩子脚本、配置文件等;任何时候运行这个脚本都得到一个版本库的安全拷贝,不管是否有其他进程正在使用版本库。

    svnadmin dump输出指定的修订版本。使用--revision选项可以指定一个单独的修订版本,或者一个修订版本的范围。如果忽略这个选项,所有版本库中的修订版本都会被转储。
    Subversion在转储修订版本时,仅会输出与前一个修订版本之间的差异,通过这些差异足以从前一个修订版本中重建当前的修订版本。换句话说,在转储文件中的每一个修订版本仅包含这个修订版本作出的修改。这个规则的唯一一个例外是当前svnadmin dump转储的第一个修订版本。默认情况下,Subversion第一个转储的修订版本默认情况下会完整的保存目录、文件以及属性等数据。不过,这些都是可以改变的。如果转储时设置了--incremental选项,svnadmin会比较第一个转储的修订版本和版本库中前一个修订版本,就像对待其它转储的修订版本一样。转储时也是一样,转储文件中将仅包含第一个转储的修订版本的增量信息。这样的好处是,可以创建几个连续的小体积的转储文件代替一个大文件,比如:
    $ svnadmin dump myrepos --revision 0:1000 > dumpfile1
    $ svnadmin dump myrepos --revision 1001:2000 --incremental > dumpfile2
    $ svnadmin dump myrepos --revision 2001:3000 --incremental > dumpfile3
    这些转储文件可以使用下列命令装载到一个新的版本库中,比如:
    $ svnadmin load newrepos < dumpfile1
    $ svnadmin load newrepos < dumpfile2
    $ svnadmin load newrepos < dumpfile3

    svnlook 是Subversion提供的用来查看版本库中不同的修订版本和事务。svnlook youngest命令不需要选项,只会显示出HEAD的修订版本号。

    【通用函数脚本】

      1 #!/bin/bash
      2 #Filename: tools.sh
      3 #***********************************************************
      4 #This scripts for set up svn backup environment
      5 #Author: qyddbear     
      6 #Email:                               
      7 #DATE:2012/05/23
      8 #Last modified by qyddbear on 2012/8/3 
      9 #***********************************************************
     10 
     11 setup_env()
     12 {
     13     DUMP="/usr/bin/svnadmin dump"
     14     LOOK="/usr/bin/svnlook youngest"
     15     HOTCOPY="/usr/bin/svnadmin hotcopy"
     16     SVN_ROOT=/home/svn
     17     SVN_BACKUP=/mnt/svn_backup
     18     BACKUP_DATE=$(date +%Y-%m-%d)
     19     ERROR_LOG=$SVN_BACKUP/backup_error.log
     20     THIS_FILE_NUM=$SVN_BACKUP/this_repo_version.log
     21     LAST_FILE_NUM=$SVN_BACKUP/last_repo_version.log
     22     ALL_BACKUP_NUM=$SVN_BACKUP/all_backup_version.log
     23 
     24     if [ $1 == "full" ];then
     25         SVN_BACKUP_DIR=$SVN_BACKUP/"full_"$BACKUP_DATE
     26         LOGFILE=$SVN_BACKUP/full_backup.log
     27     else
     28         SVN_BACKUP_DIR=$SVN_BACKUP/"increment_"$BACKUP_DATE
     29         LOGFILE=$SVN_BACKUP/increment_backup.log
     30     fi
     31 
     32     REPO_NAME_LIST=$(ls $SVN_ROOT)
     33     echo $LOGFILE
     34     echo $SVN_BACKUP_DIR
     35 }
     36 
     37 check_mount_point()
     38 {
     39     echo $1
     40     ping -c 1 -w 1 $1 &>/dev/null
     41     if [ $? = 0 ]
     42     then
     43         df -k | grep $1 &>/dev/null || mount $1:/home /mnt
     44         return 0
     45     else
     46         echo "$BACKUP_DATE==>Backup Computer[$1] already shutdown!" >>$ERROR_LOG 
     47          echo " " >>$ERROR_LOG
     48         return 1 
     49     fi
     50 }
     51 
     52 
     53 #=====================================================================
     54 #check backup directory, if not exist, mkdir
     55 #=====================================================================
     56 check_backup_dir()
     57 {
     58     if [ ! -d $SVN_BACKUP ];then
     59          mkdir $SVN_BACKUP
     60          chmod g+s $SVN_BACKUP
     61     fi
     62 
     63     if [ -d $SVN_BACKUP_DIR ];then
     64          echo "Thers is no need backup again!" >>$LOGFILE
     65     else
     66          mkdir $SVN_BACKUP_DIR 
     67          chmod g+s $SVN_BACKUP_DIR 
     68     fi
     69 }
     70 
     71 
     72 send_emails()
     73 {
     74     if [ $1 == "succeed" ];then
     75          MAILBODY=
     76     else
     77         MAILBODY=
     78     fi
     79     echo $MAILBODY | mail -s $1 qyddbear@123.com
     80 }
     81 
     82 
     83 start_full_backup()
     84 {
     85     echo " ">>$LOGFILE
     86     echo "********************$(date +%Y-%m-%d_%T)********************" >>$LOGFILE
     87     for repo_name in $REPO_NAME_LIST
     88     do
     89         #get repo version
     90          get_repo_version=$($LOOK $SVN_ROOT/$repo_name)
     91         
     92          #hotcopy full backup, key step
     93          $HOTCOPY $SVN_ROOT/$repo_name $SVN_BACKUP_DIR/$repo_name
     94                echo "$(date +%T)==> repository:[$repo_name] at version($get_repo_version) Hotcopy Successfull Full Backup !" >>$LOGFILE
     95          echo " ">>$LOGFILE
     96 
     97         #dump full backup, key step
     98         $DUMP $SVN_ROOT/$repo_name > $SVN_BACKUP_DIR/"$repo_name"_"0"-"$get_repo_version".dump
     99                echo "$(date +%T)==> repository:[$repo_name] at version($get_repo_version) Dump Successfull Full Backup !" >>$LOGFILE
    100          echo " ">>$LOGFILE
    101 
    102          #output full repo version number to a txt for incremental backup usage
    103          echo "$get_repo_version" > $LAST_FILE_NUM 
    104         echo "$get_repo_version" >> $ALL_BACKUP_NUM
    105     done
    106 }
    107 
    108 
    109 start_increment_backup()
    110 {    
    111     echo " ">>$LOGFILE
    112     echo "*******************$(date +%Y-%m-%d_%T)******************" >>$LOGFILE
    113       for repo_name in $REPO_NAME_LIST
    114       do
    115         lastnum=$(cat $LAST_FILE_NUM)
    116         echo "$(date +%T)==> repository:[$repo_name] last time version_number : $lastnum" >>$LOGFILE
    117         let beginnum=($lastnum+1)
    118         echo "$(date +%T)==> repository:[$repo_name] increment backup will begin from : $beginnum" >> $LOGFILE
    119         thisnum=$($LOOK $SVN_ROOT/$repo_name)
    120         echo "$(date +%T)==> repository:[$repo_name] this time version_number : $thisnum" >>$LOGFILE
    121         
    122             if [ $thisnum -ne $lastnum ];then
    123             $DUMP $SVN_ROOT/$repo_name -r $beginnum:$thisnum --incremental > $SVN_BACKUP/increment_"$BACKUP_DATE"/"$repo_name"_"$beginnum"-"$thisnum".dump
    124             echo "$(date +%T)==> repository:[$repo_name] version(from $beginnum to $thisnum) backup successful!" >>$LOGFILE
    125         else
    126                   echo "$(date +%T)==> repository:[$repo_name] has no new version!!" >>$LOGFILE
    127             
    128         fi
    129     echo " ">>$LOGFILE
    130     echo "$thisnum" > $LAST_FILE_NUM
    131     echo "$thisnum" >> $ALL_BACKUP_NUM
    132     done
    133     
    134 }

    【全量备份脚本】

     1 #!/bin/bash
     2 #Filename: svn_full_backup.sh
     3 #*******************************************************
     4 #This scripts for svn full bakcup
     5 #Author: qyddbear     
     6 #Email:                            
     7 #DATE:2012/05/23 
     8 #Last modified by qyddbear on 2012/8/3 
     9 #*******************************************************
    10 
    11 . ./tools.sh
    12 
    13 setup_env full
    14 
    15 #backup server ip
    16 check_mount_point 192.168.1.66
    17 
    18 check_backup_dir
    19 
    20 start_full_backup

    【增量备份脚本】

     1 #!/bin/bash
     2 #Filename: svn_increment_backup.sh
     3 #*******************************************************
     4 #This scripts for svn increment bakcup
     5 #Author: qyddbear    
     6 #Email:                            
     7 #DATE:2012/05/24 
     8 #Last modified by qyddbear on 2012/8/3
     9 #*******************************************************
    10 
    11 . ./tools.sh
    12 
    13 setup_env increment
    14 
    15 #backup server ip
    16 check_mount_point 192.168.1.66
    17 
    18 check_backup_dir
    19 
    20 start_increment_backup

    【设置备份时间】

    配置 /etc/crontab 文件,用crontab来定在每周6的23:30分执行任务:

    30 23 * * 6 /home/scripts/svn_full_backup.sh
    重新启动/etc/init.d/crond restart
     
    注:前五个以4个空格分隔开的值依次表示:分、时、日、月、周,如果取所有值就是打*号,如果想周期性的运行一个任务,crontab也接受范围指定,比如说一天中的早8点到晚6点每隔一小时(就是每两小时,将会在8,10,12,14,16,18执行)执行,这个删除命令这样写:

    * 8-18/2 * * * root rm -rf /root/febhost/dat/* /root/febhost/log/*
    第一个字段是分钟,取值范围:0-59
    第二个字段是小时。取值范围:0-23
    第三个字段是一个月中的第几天,取值范围:1-31
    第四个字段是一年中的第几个月,取值范围:1-12
    最后一个字段是一个星期中的第几天,以星期天开始依次的取值为0~7,0、7都表示星期天。
    下一个字段是执行该命令的用户身份,这里是root用户,最后一个字段就是定时运行的命令。

     
    【如何知道备份是否完整呢?】
     
    备份完整性检查的思路是:对备份的库运行 svnlook youngest,如果能正确打印出最新的版本号,则表明备份文件没有缺失;如果备份中断,则运行svnlook youngest会出错,说明备份不完整。

    【备份恢复】

    首先要建立一个新的版本库:
    svnadmin create --fs-type=fsfs /home/svn/project
    然后再执行load,还原数据。恢复顺序从低版本逐个恢复到高版本;即,先恢复最近的一次完整备份 weekly_full_backup.071201(举例),然后恢复紧挨着这个文件的增量备份 daily_incremental_backup.071202,再恢复后一天的备份071203,依次类推。如下: 
    svnadmin load /home/svn/project < /home/backup/svn/weekly_full_backup.071201 
    svnadmin load /home/svn/project < /home/backup/svn/daily_incremental_backup.071202 
    svnadmin load /home/svn/project < /home/backup/svn/daily_incremental_backup.071203 
     
  • 相关阅读:
    Android官方数据绑定框架DataBinding*
    Application 使用分析*
    Android HandlerThread与IntentService*
    Android中SQLite应用详解*
    Android开发中,那些让您觉得相见恨晚的方法、类或接口*
    巧用ViewPager 打造不一样的广告轮播切换效果*
    Android-Universal-Image-Loader的缓存处理机制与使用 LruCache 缓存图片*
    Android Volley完全解析*
    Android 蓝牙*
    Android自定义View
  • 原文地址:https://www.cnblogs.com/qyddbear/p/2862112.html
Copyright © 2011-2022 走看看