Follow GFI:
Find us on Facebook Follow us on Twitter Find us on Linkedin Subscribe to our RSS Feed Find us on YouTube Find us on Google+
 

The SVN recovery story

on October 9, 2009

So it happened that the disk hosting our code repository developed some bad blocks. Must be contagious or something, this is already the third system within a month…

I noticed this, when I received some strange messages from cron. Basically my backup script started failing when svnadmin dump could not read a file. On closer examination, one of the DIFF files in the svn repository was damaged. This was bad, as the content is stored as a series of diffs, and a particular branch of the repository became unavailable.

The Subversion aka SVN repository is located on /var a separate partition. Since /var receives a lot of writes, I decided to migrate the whole /var to a different partition to avoid further bad blocks.

Armed with rsync and ddrescue I started the recovery process. You know the drill; format the new partition, rsync the content and ddrescue the damaged file. But this time ddrescue let me down. Now it was time for backups to step in.

Satisfied with a quick solution – restore from backup, I stopped all services which were using /var, unmounted it, mounted the new partition as /var and restarted all previously stopped services.

To my surprise the SVN still did not want to cooperate. I was getting a bad feeling about this, which was confirmed after examining all eleven weekly backups. In all of them the file was corrupted.

How did I not notice this earlier? Well, it was time to think about a new strategy.

I tried to run svnadmin recover mode, but that didn’t yield anything.

I don’t know the internal workings of SVN, but what I figured out is:

  • content is stored as diffs
  • each commit is one big file containing all changes
  • there is file containing the number of the current revision

Luckily I knew exactly what files were committed in that particular diff, even better for me, it was a commit of only a few new big files! My best chance would be to recreate the corrupted commit.

When I manipulated the revision counter, the SVN server was tricked into thinking that the ‘current’ version was whatever I set it to be.

So I rolled back the revision counter to the revision before corruption, checked out the branch with TortoiseSVN into a new location, included the ‘new’ files and committed them to the repository. Re-setted the revision counter to original and voila, everything started working!

I guess this time I got more luck than brain. What would you do?

All product and company names herein may be trademarks of their respective owners.