Linux – In subversion how can I create a slave repository from the master at the current revision

backuplinuxsvn

I have a huge subversion repository and want to create a slave repository for live backup purposes.

However I do not want to replay the revision history into the slave because this will literally take days due to the size of my repository. I already have the usual infrastructure in place such as hook scripts and two web servers that serve the master and the soon to be slave repository.

How do I do this?

Best Answer

Subversion has the ability to support one or more slave repositories which you can cynchronise using hook scripts or you could use a cron job that runs svnsync for you. When you create a slave repository the procedure involves, amongst other things, creating a repository with only revision 0 and then you replay all the commits from the master to that slave. Depending on your bandwidth and the size of the repository this can take a very long time.

There is a quicker way to do this. It involves copying the current master to the new location and then perform some tricks to turn it into a slave. I'll leave the actual implementation of automatic or live synchronisation up to you.

In this answer we assume:

  • The repository's name is "repo"
  • The master server is reachable through the filesystem
  • The slave server is reachable at https://slave.example.org/repo

I have used this method many times with a 20+ GB subversion repository, I also successfully recovered a broken master a few times by copying a slave, created in this way, back to the master.

We will copy the master and transfer it to the remote server, in the directory where your repository resides do:

svnadmin hotcopy repo repo_bak
tar -cjf repo_bak.tar.bz repo_bak
scp repo_bak.tar.bz user@slave.example.org:/path/

The hotcopy command allows you to safely copy a repository that's currently in use and keep it consistent.

Unpack the tarball on the slave server and all that...

We assume that on the slave server you are running a web server that is configured to serve the repository in the usual way. In addition it needs hooks scripts which prevent any account except the synchronisation account to commit, for obvious reasons, we want the repositories to be exactly the same. Again how to do that is outside the scope of this answer.

We run all the below commands on the master repository.

Bind the master repository to the slave repository:

svn propset svn:sync-from-url --revprop -r 0 file:///example/path/repo https://slave.example.org/repo

Find out the revision of the slave repository, this will also give you the UUID which you will need below:

svn info https://slave.example.org/repo

Use the revision you found above in the following command:

svn propset svn:sync-last-merged-rev --revprop -r 0 REVISION_OF_SLAVE https://slave.example.org/repo

We need to use the UUID we found above to add to the master repository:

svn propset svn:sync-from-uuid --revprop -r 0 UUID_OF_SLAVE https://slave.example.com/repo

If everything went well you can now successfully synchronise the slave:

svnsync sync https://slave.example.org/repo