He estado siguiendo la discusión sobre el "error" en EXT4 que hace que los archivos se pongan a cero en crash si se usa el proceso "crear archivo temporal, escribir archivo temporal, cambiar el nombre de la temperatura al archivo destino". POSIX dice que a menos que se llame a fsync(), no puede estar seguro de que los datos se hayan descargado al disco duro.¿Manera segura y eficiente de modificar archivos múltiples en sistemas POSIX?
Obviamente haciendo:
0) get the file contents (read it or make it somehow)
1) open original file and truncate it
2) write new contents
3) close file
no es bueno incluso con fsync() que el equipo puede bloquearse durante 2) o fsync() y se termina con el archivo escrito parcialmente.
Por lo general, se ha pensado que esto es bastante seguro:
0) get the file contents (read it or make it somehow)
1) open temp file
2) write contents to temp file
3) close temp file
4) rename temp file to original file
Por desgracia no lo es. Para que sea más seguro en EXT4 que tendría que hacer:
0) get the file contents (read it or make it somehow)
1) open temp file
2) write contents to temp file
3) fsync()
4) close temp file
5) rename temp file to original file
esto sería seguro y el accidente se debe o bien tienen los nuevos contenidos de los archivos o contenidos antiguos, no reducidos a cero o contenido parcial. Pero si la aplicación usa muchos archivos, fsync() después de cada escritura sería lento.
Así que mi pregunta es, ¿cómo modificar múltiples archivos de manera eficiente en un sistema donde fsync() es necesario para asegurarse de que los cambios se hayan guardado en el disco? Y realmente me refiero a modificar muchos archivos, como en miles de archivos. Modificar dos archivos y hacer fsync() después de cada uno no sería tan malo, pero fsync() ralentiza las cosas al modificar varios archivos.
EDITAR: cambió el archivo fsync() close temp al orden corrent, se le dio más énfasis a la escritura de muchos y muchos archivos.
Con el método de renombrado uno podría escribir 100.000 archivos de configuración sin un fsync(), y hacer 100.000 fsync() sería lento. – Raynet
"desea que los datos escritos en el disco al cierre() de todos modos" ¿De qué estás hablando? Se supone que Close solo desasigna la descripción del archivo de acuerdo con POSIX. No es necesario vaciar los almacenamientos intermedios. http://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html – ArekBulski