Suppose svn_fs_commit_txn fails to complete, either due to a transient
error like disk full or file permissions, or because the process is
killed. Further suppose that the transaction remains on disk. Is it
valid to call svn_fs_commit_txn again on the same transaction? There
doesn't seem to be anything to prohibit it but the FSFS implementation
can lead to revision files that are not correct.
Each transaction has a protorev file containing the file representations
built up during the transaction. When svn_fs_commit_txn is called the
protorev file is expected to contain just the sequence of file reps.
The commit code appends the node reps, change lists, etc. to the
protorev file and then moves it to create the new revision file. What
happens when svn_fs_commit_txn is interrupted and retried depends on
when the interrupt occurs. An interrupt after appending but before
moving will leave the appended data in the protorev file, and then a
retry will add the appended data a second time. The result is a
revision file that contains duplicate nodes, multiple change lists, etc.
The problem is likely even worse if changes are made to the transaction
between the calls to svn_fs_commit_txn.
So, is it valid to retry svn_fs_commit_txn? Is it valid to modify the
transaction after svn_fs_commit_txn fails? If it is valid we should
probably try to make the result independent of the number of attempts.
If it is not valid we should probably try to make the attempts fail.
This is mostly a theoretical problem at present: servers and clients
tend to delete transactions when svn_fs_commit_txn fail and so no retry
is possible.
In the long term perhaps we should dispense with the protorev file. We
could stored file reps in individual files in the transaction directory
and build the revision file from scratch. There would be an IO penalty,
writing the file reps twice, but we might gain the ability to write
file reps into the transaction in parallel.
--
Philip Martin | Subversion Committer
WANdisco // *Non-Stop Data*
Received on 2013-11-26 12:53:41 CET