
So there are two servers; let's call them srv1 and srv2. Srv1
contains a bunch of subversion repositories, but these are to be
migrated to srv2. Since the repositories are not (just) used for
ascii-only files, they're fairly big (several tens of gigabytes,
altogether), so copying them from one server to the other would take a
while. In order to make sure this would happen quickly, we had already
copied them over to the new server, so that on the final switch would be
quick (an rsync that would copy over just the new done
transactions).
That final switch was today. Only I didn't know that instead of just
testing, the customer had already started using one of the repositories
(and they'd forgotten to remind me), so the subversion repository
suddenly jumped backwards in time. In addition, the new server wasn't
being backed up yet (at least not for the subversion bits), so restoring
from backups wasn't an option. Oops.
Luckily the solution is fairly simple. You see, fsfs stores each
revision in a unique file; that means that as long as nobody has
committed to the repository yet (which they couldn't, since system users
aren't the same on both servers, so the webserver didn't have write
permissions on the repository after the rsync), nothing is lost. One
only needs to manually change the repository so that whatever subversion
thinks is the latest commit, actually
is the latest commit.
That information is stored in a file called
db/current
inside the repository. What's in that file depends on the repository
version, which is stored in a file called
db/format in the
repository. For versions 1 and 2, the format is a single line with three
space-separated values, of which the first is the last revision number
used in the repository. The other two are counters that are used to give
transactions unique names; and they, too, need to be up-to-date. For
version 3 and above, the file contains only the revision number; there,
the other two are derived from that instead of having their own unique
number.
Figuring out the last used revision number in an fsfs repository is
ridiculously easy:
ls -v db/revs tail -n1
So if you've got a repository of fsfs version 3 or above, just change
the revision number in the
db/current file (
after
taking backups and making sure nobody can access the repository while
you're doing this, of course), and you're all set.
Unfortunately, in my case, the repository was still in fsfs version
2, which meant I could not change
just the revision number and
not expect trouble. I suppose it should've been possible to figure out
what the last transaction numbers are, somehow, so that I could fix the
current file completely, but I reasoned that upgrading to a
newer repository format might have other advantages too, so I just
dumped the repository and reloaded it, and everything worked at that
point.