Now with Comments

Want to say something?

Read more...
Back
Backup a Subversion (SVN) Repository with this Free Script PDF Print E-mail
User Rating: / 5
PoorBest 
Written by Anthony Hildoer   
Sunday, 22 November 2009 09:02

Version control systems are probably one of the most useful tools I have ever found. I store everything from shell scripts, to source code, to family photos, to configuration files, to the kitchen sink. And, since I run my own Subversion serve, I can create repositories with abandon. In fact, each software module I develop for each customer gets a private repository. Considering how dependent I am on Subversion, it only follows that I need to make sure my Subversion server is completely bullet proof, or at least thoroughly backed up. Although the drive system utilized is a RAID10 with multiple hot spares, I still did not feel secure knowing the the building could burn down and I could still lose everything. So, I needed a more integrated way of backing up Subversion, but without the price tag of expensive backup solutions one can purchase online. This is where my knack for automation scripting jumps off the bench and yells, "Put me in coach!"

Let me review the list of requirements I had in mind when I planned out this simple, but extremely useful backup script:

  1. Hot copies must be supported. I do not want to shutdown Subversion in order to do a backup. If I can accomplish this, I can schedule many backups throughout the day and never have to worry about a backup running while I am still committing to Subversion.
  2. Only one backup per repository is kept. Subversion's hot copy tool creates a different backup directory name depending on the latest revision of repository you are processing. So, even though each hot copy is a complete copy of the entire repository version history, each backup is appended with the latest commit version. If you like this feature and want multiple copies of each backup, then simply comment out the following code in the script.
    	echo `date`: Removing old backups for $repo...
    existingBackups=`ls /backup/ | grep -E $repo'-[0-9]+(-[0-9]+)?$'`
    for existingBackup in $existingBackups; do
    existingBackup="$backupDir/$existingBackup"
    echo `date`: Removing $existingBackup...
    rm -rf $existingBackup
    done
    echo `date`: Done.
  3. I need to be able to trigger a command at the end of the backup, so that I can trigger a copy of the backup directory to be sent to my offsite backup system, which at the time this tutorial was written was SpiderOak.com.

So there you have it. The 3 things my subversion backup script does. Now all you need do is download the script, set your configuration parameters in the indicated section in the source code, then chmod, then cron it up. Speaking of cron, here is my entry in /etc/crontab which I use to trigger periodic system backups:

0 */2   * * *   root    /etc/backupSVN >> /var/log/backupSVN.log 

Of course, make sure your cron entry points to the place where you save backupSVN, as you may not have picked /etc as I have.

Don't forget to chmod +x and run with sudo. Enjoy.

Download Script or copy and paste the script manually:

#!/bin/bash
 
############################### START CONFIGURATION ##################
reposPath='/var/lib/svn/'
backupDir='/backup'
postBackupCommand='/usr/bin/SpiderOak -v --batchmode'
 
repos=`ls -l --time-style=long-iso "$reposPath" | grep '^d' | sed 's/\s\s*/ /g' | cut -f8 -d" "` # select all directories in the repository directory
 
############################### END CONFIGURATION ##################
 
############################### START CODE ##################
reposPath=`echo "$reposPath" | sed 's/\/\s*$//'`
backupDir=`echo "$backupDir" | sed 's/\/\s*$//'`
 
echo `date`: Starting backups...
 
# backup all the repositories one at a time
for repo in $repos; do 
 
  echo `date`: Removing old backups for $repo...
  existingBackups=`ls "$backupDir" | grep -E $repo'-[0-9]+(-[0-9]+)?$'`
  for existingBackup in $existingBackups; do
    existingBackup="$backupDir/$existingBackup"
    echo `date`: Removing $existingBackup...
    rm -rf $existingBackup
  done
  echo `date`: Done.
 
  # calculate the full path to the repository
  repoPath=`echo "$reposPath/$repo" | sed 's/\/\//\//g'` #compbine repo dir path with current repo name, and remove any duplicate slashes
 
  # do the actual backup
  echo `date`: "Dumping $repoPath..."
  results=`svn-hot-backup "$repoPath" "$backupDir"`
  echo `date`: "Done."
 
  # grab any error lines
  error=`echo "$results" | grep -i 'error'`
 
  # see if an error line was found 
  if [ "$error" == "" ]; then
 
    # get the actual path to the backup destination
    actualBackup=`echo "$results" | grep -i 'Backing up repository to ' | sed "s/Backing up repository to '\([^\']*\)'.*$/"/"`
 
    # see what the version was for the backup
    version=`echo "$results" | grep 'Youngest revision is' | sed 's/Youngest revision is //'`
 
    # see what the backup destination would be if there was not an existing backup in place 
    correctBackup="$backupDir/$repo-$version"
 
    # see if the backup was as duplicate for the current version. if so, replace the previous backup
    if [ $actualBackup != $correctBackup ]; then
      echo `date`: "Moving actual backup '$actualBackup' destination to correct destination '$correctBackup'"
 
      # clear destination
      rm -rf "$correctBackup"
 
      # do the move
      mv "$actualBackup" "$correctBackup"
 
      # variable maintenence
      actualBackup=$correctBackup
 
    fi    
 
    echo `date`: "Successfully backed up repo $repo to $actualBackup for version $version"
  else  
    echo `date`: "Failed to backup $repo: '$results'" >&2
  fi
 
done
 
# remove all duplicate backups that remain
for repoBackup in `ls "$backupDir" | grep '[^\-\/]*-[^\-\/]*-[^\-\/]*'`; do
  path="$backupDir/$repoBackup"
  rm -rf "$path"
done
 
echo `date`: Running post backup command "$postBackupCommand"...
dateNow=`date`
postbackup=`$postBackupCommand | sed "s/^/$dateNow:\t/g"`
echo $postbackup
echo `date`: Done.
 
echo `date`: Finished backups.

Last Updated on Wednesday, 16 December 2009 08:48
 
Comments (3)
comment
1 Friday, 09 April 2010 04:14
Andy Shaun
http://www.google.com
bug for repositories with dash line inside its name
2 Tuesday, 17 August 2010 12:25
Piotr Rezmer
Hi,
When repository contains dash line (e.g. java-crmClient) destination folder is deleted after hotcopy.
Temporarily I commented out all lines starting with 'rm'
backup security
3 Tuesday, 17 August 2010 14:50
Piotr Rezmer
Hi,
I'm just wondering if it's safe to delete existing backups at the beggining of the script. What happens if svn-hotcopy fails? We'll loose existing backup so it won't be possible to retrieve data.

Add your comment

Your name:
Your email:
Subject:
Comment:
  The word for verification. Lowercase letters only with no spaces.
Word verification:
Content View Hits : 131511