2012-09-04 19 views
6

Hay una región en el archivo (posiblemente pequeña) que quiero sobrescribir. Supongamos que llamo fseek, fwrite, fsync. ¿Hay alguna forma de garantizar la atomicidad de dicha operación de reescritura regional, p. Necesito estar seguro de que, en cualquier caso de falla, la región solo contendrá datos antiguos (antes de la modificación), o solo datos nuevos (modificados), pero no una combinación de esto.Modificación de archivo atómico

Hay dos cosas que quiero resaltar.

Primera: Está bien si no hay manera de escribir atómicamente cualquier región del tamaño - podemos manejarlo anexando los datos en el fichero, fsync'ing, y luego volver a escribir zona 'puntero' en el archivo, a continuación, de nuevo fsyncing . Sin embargo, si la escritura 'puntero' no es atómica, aún podemos tener un archivo dañado con punteros ilegales.

Segundo: Estoy bastante seguro, escribir regiones de 1 byte es atómico: no veré en el archivo los bytes que nunca coloqué allí. Así que podemos usar algunos trucos para asignar dos regiones para las direcciones y usar el interruptor de 1 byte, así que volver a escribir la región se convirtió en: agregar datos nuevos, sincronizar, reescribir uno de dos espacios del puntero (sin usar), sincronizar nuevamente y luego reescribir 'cambiar byte 'y una vez más la sincronización. Entonces la operación de sobreescribir región ahora contiene al menos 3 invocación fsync.

Todo esto sería mucho más fácil, si tendré escritura atómica por largos, ¿pero realmente la tengo?

¿Hay alguna forma de manejar esta situación sin usar el método mencionado en el punto 2?

Otra pregunta es: ¿hay alguna garantía de pedido entre la escritura y la sincronización? Por ejemplo, si llamo a fseek, fwrite [1], fseek, fwrite [2], fsync, ¿puedo escribir en [2] commited, y escribir en [1] - no commited?

Esta pregunta es aplicable al sistema operativo Linux y Windows, cualquier respuesta en particular (por ejemplo, en la versión ubuntu a.b.c ....) también es necesaria.

+0

[fsync] (http://linux.die.net/man/3/fsync) parece ser bastante aplicación/sistema de archivos dependientes. http://blogs.gnome.org/alexl/2009/03/16/ext4-vs-fsync-my-take/ – zapl

+0

Lo que estás hablando se conoce como "control de compromiso", o "commit/rollback", o "transacciones". –

+0

(La única forma (casi) totalmente confiable de hacer lo que usted desea, a falta de alguna función de procesamiento de transacciones en la caja, es hacer el viejo intercambio de archivos: copiar el archivo antiguo a nuevo, cambiar el nuevo, renombrar nuevo para reemplazar el anterior). –

Respuesta

1

Por lo general, es seguro asumir que los discos duros escriben un trozo de 512 bytes en una escritura. Sin embargo, no asumiría eso. En su lugar, elegiría su segunda solución, mientras agregaba una suma de comprobación a su escritura y la verificaba antes de cambiar el puntero en el archivo.

En general, es una buena práctica agregar suma de comprobación a todo lo escrito en el disco.

Para responder sobre la garantía de "sincronización", puede suponer eso. Si bien la sincronización es FS y depende del disco, digamos que estamos hablando de una implementación "razonable".

  • Después de la primera sync se garantiza que los datos sean vaciadas al disco (el disco podría tener que en su caché todavía) y si los datos que se espera para conseguir lo que escribió.
  • Si después de la segunda sync los datos de ambas sincronizaciones están en la memoria caché de disco, la situación que describió puede suceder, pero IMHO la probabilidad de que sea muy baja.

De todos modos, no hay otro mecanismo que prometa que la información está en el disco. Es por eso que debe tener sumas de verificación.

algo más de información: Ensure fsync did its job

+0

Gracias por su respuesta. Acerca de la garantía de 'sincronización', ¿puede proporcionarme una "prueba" para esta suposición? O, ¿proviene de algún (¿qué?) Código de seguimiento/experto (¿cuál?) Aconseja? – andll

+0

aumentó la respuesta con algo de información. – Drakosha

Cuestiones relacionadas