| "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. |