blob: ea880b5ce6b737fda6a14afa1ecb2e2adcdcf7d8 [file] [log] [blame]
"FSFS" is the name of a Subversion filesystem implementation, an
alternative to the original Berkeley DB-based implementation. See
http://subversion.apache.org/ for information about Subversion. This
is a propaganda document for FSFS, to help people determine if they
should be interested in using it instead of the BDB filesystem.
How FSFS is Better
------------------
* Write access not required for read operations
To perform a checkout, update, or similar operation on an FSFS
repository requires no write access to any part of the repository.
* Little or no need for recovery
An svn process which terminates improperly will not generally cause
the repository to wedge. (See "Note: Recovery" below for a more
in-depth discussion of what could conceivably go wrong.)
* Smaller repositories
An FSFS repository is smaller than a BDB repository. Generally, the
space savings are on the order of 10-20%, but if you do a lot of work
on branches, the savings could be much higher, due to the way FSFS
stores deltas. Also, if you have many small repositories, the
overhead of FSFS is much smaller than the overhead of the BDB
implementation.
* Platform-independent
The format of an FSFS repository is platform-independent, whereas a
BDB repository will generally require recovery (or a dump and load)
before it can be accessed with a different operating system, hardware
platform, or BDB version.
* Can host on network filesystem
FSFS repositories can be hosted on network filesystems, just as CVS
repositories can. (See "Note: Locking" for caveats about
write-locking.)
* No umask issues
FSFS is careful to match the permissions of new revision files to the
permissions of the previous most-recent revision, so there is no need
to worry about a committer's umask rendering part of the repository
inaccessible to other users. (You must still set the g+s bit on the
db directories on most Unix platforms other than the *BSDs.)
* Standard backup software
An FSFS repository can be backed up with standard backup software.
Since old revision files don't change, incremental backups with
standard backup software are efficient. (See "Note: Backups" for
caveats.)
(BDB repositories can be backed up using "svnadmin hotcopy" and can be
backed up incrementally using "svnadmin dump". FSFS just makes it
easier.)
* Can split up repository across multiple spools
If an FSFS repository is outgrowing the filesystem it lives on, you
can symlink old revisions off to another filesystem.
* More easily understood repository layout
If something goes wrong and you need to examine your repository, it
may be easier to do so with the FSFS format than with the BDB format.
(To be fair, both of them are difficult to extract file contents from
by hand, because they use delta storage, and "db_dump" makes it
possible to analyze a BDB repository.)
* Faster handling of directories with many files
If you are importing a tree which has directories with many files in
it, the BDB repository must, by design, rewrite the directory once for
each file, which is O(n^2) work. FSFS appends an entry to the
directory file for each change and then collapses the changes at the
end of the commit, so it can do the import with O(n) work.
Purely as a matter of implementation, FSFS also performs better
caching, so that iterations over large directories are much faster for
both read and write operations. Some of those caching changes could
be ported to BDB without changing the schema.
* (Fine point) Fast "svn log -v" over big revisions
In the BDB filesystem, if you do a large import and then do "svn log
-v", the server has to crawl the database for each changed path to
find the copyfrom information, which can take a minute or two of high
server load. FSFS stores the copyfrom information along with the
changed-path information, so the same operation takes just a few
seconds.
* (Marginal) Can give insert-only access to revs subdir for commits
In some filesystems such as AFS, it is possible to give insert-only
write access to a directory. If you can do this, you can give people
commit access to an FSFS repository without allowing them to modify
old revisions, without using a server.
(The Unix sticky bit comes close, but people would still have
permission to modify their own old revisions, which, because of delta
storage, might allow them to influence the contents of other people's
more recent revisions.)
How FSFS is Worse
-----------------
Most of the downsides of FSFS are more theoretical than practical, but
for the sake of completeness, here are all the ones I know about:
* More server work for head checkout
Because of the way FSFS stores deltas, it takes more work to derive
the contents of the head revision than it does in a BDB filesystem.
Measurements suggest that in a typical workload, the server has to do
about twice as much work (computation and file access) to check out
the head. From the client's perspective, with network and working
copy overhead added in, the extra time required for a checkout
operation is minimal, but if server resources are scarce, FSFS might
not be the best choice for a repository with many readers.
* Finalization delay
Although FSFS commits are generally faster than BDB commits, more of
the work of an FSFS commit is deferred until the final step. For a
very large commit (tens of thousands of files), the final step may
involve a delay of over a minute. There is no user feedback during
the final phase of a commit, which can lead to impatience and, in
really bad cases, HTTP client timeouts.
* Lower commit throughput
Because of the greater amount of work done during the final phase of a
commit, if there are many commits to an FSFS repository, they may
stack up behind each other waiting for the write lock, whereas in a
BDB repository they would be able to do more of their work in
parallel.
* Less mature code base
FSFS was introduced in the Subversion 1.1 release, whereas BDB has
been around since the inception of the Subversion project.
* Big directories full of revision files
Each revision in an FSFS repository corresponds to a file in the
db/revs directory and another one in the db/rev-props directory. If
you have many revisions, this means there are two directories each
containing many files. Though some modern filesystems perform well on
directories containing many files (even if they require a linear
search for files within a directory, they may do well on repeated
accesses using an in-memory hash of the directory), some do not.
Subversion 1.5 addresses this issue by optionally organizing revision
files and revprop files into sharded subdirectories.
* (Developers) More difficult to index
Every so often, people propose new Subversion features which require
adding new indexing to the repository in order to implement
efficiently. Here's a little picture showing where FSFS lies on the
indexing difficulty axis:
Ease of adding new indexing
harder <----------------------------------> easier
FSFS BDB SQL
With a hypothetical SQL database implementation, new indexes could be
added easily. In the BDB implementation, it is necessary to write
code to maintain the index, but transactions and tables make that code
relatively straightforward to write. In a dedicated format like FSFS,
particularly with its "old revisions never change" constraint, adding
new indexing features would generally require a careful design
process.
How To Use
----------
FSFS support is new in Subversion 1.1. If you are running a
Subversion 1.0.x release, you will need to upgrade the server (but not
the client, unless you are using file:/// access).
Once you've gotten that out of the way, using FSFS is simple: just
create your repositories with "svnadmin create --fs-type=fsfs PATH".
Or, build Subversion without Berkeley DB support, and repositories
will be created with FSFS by default.
Note: Recovery
--------------
If a process terminates abnormally during a read operation, it should
leave behind no traces in the repository, since read operations do not
modify the repository in any way.
If a process terminates abnormally during a commit operation, it will
leave behind a stale transaction, which will not interfere with
operation and which can be removed with a normal recursive delete
operation.
If a process terminates abnormally during the final phase of a commit
operation, it may be holding the write lock. The way locking is
currently implemented, a dead process should not be able to hold a
lock, but over a remote filesystem that guarantee may not apply.
Also, in the future, FSFS may have optional support for
NFSv2-compatible locking which would allow for the possibility of
stale locks. In either case, the write-lock file can simply be
removed to unblock commits, and read operations will remain
unaffected.
Note: Locking
-------------
Locking is currently implemented using the apr_file_lock() function,
which on Unix uses fcntl() locking, and on Windows uses LockFile().
Modern remote filesystem implementations should support these
operations, but may not do so perfectly, and NFSv2 servers may not
support them at all.
It is possible to do exclusive locking under basic NFSv2 using a
complicated dance involving link(). It's possible that FSFS will
evolve to allow NFSv2-compatible locking, or perhaps just basic O_EXCL
locking, as a repository configuration option.
Note: Backups
-------------
Naively copying an FSFS repository while a commit is taking place
could result in an easily-repaired inconsistency in the backed-up
repository. The backed-up "current" file could wind up referring to a
new revision which wasn't copied, or which was only partially
populated when it was copied.
[ Update: as of 1.6, FSFS uses an optional SQLite DB, rep-cache.db, when
rep-sharing is enabled. SQLite provides no guarantee that copying live
databases will result in copies that are uncorrupt, or that are corrupt but
will raise an error when accessed. 'svnadmin hotcopy' avoids the problem by
establishing an appropriate SQLite lock (see svn_sqlite__hotcopy()). User
code should either use an atomic filesystem snapshot (as with zfs/LVM),
refrain from copying rep-cache.db, or stop all access to that file before
copying it (for example, by disabling commits, by establishing a lock a la
svn_sqlite__hotcopy(), or by using 'svnadmin freeze'). ]
The "svnadmin hotcopy" command avoids this problem by copying the
"current" file before copying the revision files. But a backup using
the hotcopy command isn't as efficient as a straight incremental
backup. As of Subversion 1.5.0, "svnadmin recover" is able to recover
from the inconsistency which might result from a naive backup by
recreating the "current" file. However, this does require reading
every revision file in the repository, and so may take some time.
Naively copying an FSFS repository might also copy in-progress
transactions, which would become stale and take up extra room until
manually removed. "svnadmin hotcopy" does not copy in-progress
transactions from an FSFS repository, although that might need to
change if Subversion starts making use of long-lived transactions.
So, if you are using standard backup tools to make backups of a FSFS
repository, configure the software to copy the "current" file before
the numbered revision files, if possible, and configure it not to copy
the "transactions" directory. If you can't do those things, use
"svnadmin hotcopy", or be prepared to cope with the very occasional
need for repair of the repository upon restoring it from backup.