Hammer: Transactional file updates

Michael Neumann mneumann at ntecs.de
Fri Aug 1 10:19:48 PDT 2008


Matthew Dillon wrote:
:Hi,
:
:So Hammer does not guarantee "transctional consistency" of data in case
:of a crash, only that of meta-data, right?
:
:Is there a method to guarantee the write to be transactional, so that
:I either have the previous "version" of the file or the version that I
:wrote? Like this:
:
:   fd = open(file);  // behaves like START TRANSACTION
:   read(fd, ...);
:   write(fd, ...);
:   close(fd);        // behaves like COMMIT
:
:That would be incredible cool (and very useful!) and could play well due
:to Hammers historical nature.
:
:I know I could probably solve this issue by creating a new file,
:fsyncing it and then doing a "rm old_file; mv new_file old_file" (or
:something like that), but that would give me a new inode number, which
:I'd like to avoid.
:
:Regards,
:
:   Michael
    Well, you will never see garbage in the data, but there is no
    integrated API available for enclosing multiple operations in a
    single transaction.
Note that I was looking for "enclosing multiple operations *to the same
file* in a single transaction".
    If you do a sequence of write()'s and nothing else the blocks will be
    committed to the media at the operating system's whim, meaning not
    necessarily in order, so a crash would result in spotty updates of the
    file's data.  You will never get garbage like you can with UFS, but it
    is not an all-or-nothing situation either.
So each write() is all-or-nothing?

    Can an arbitrary transactional API be implemented in HAMMER?  Yes, it
    can.  This is how you do it:
    * run 'hammer synctid' to get a snapshot transction id, write the TID
      to a file somewhere.  fsync().
    * issue the operations you want to be atomic

    * run 'hammer synctid' to get a snapshot transction id, write the TID
      to a file somewhere.  fsync().
    If a crash occurs during the sequence you can do a selective rollback
    to the recorded TID for the portion of the filesystem you modified.
    It could be done now, in fact, by using something like:
	# perform rollback
	cpdup -V directory@@<snapshot> directory
Hm, I was thinking more in terms of per-file transactions, not
neccessarily whole-filesystem transactions. I think what you describe
wouldn't be too efficient when compared against a MVCC database. What I
need could be implemented using temporary files:
  * lock original file

  * create temporary file

  * write temporary file

  * fsync temporary file

  * rename original file to something else

  * rename temporary file to original file

  * unlock

That would be fine except that it would give me a new inode number, and
the inode number is right now the only way to associate further data
with a file.
Could that style of transactional-writes (per file) be implemented in
Hammer?
Regards,

  Michael





More information about the Users mailing list