7 de abril de 2009

Mucho, mucho ruido sobre Ext4...

Habrán leido desde hace unas semanas un montón de artículos sobre un supuesto problema de Ext4. En la mayoría de sitios la cosa ha degenerado hasta el punto de hablar de corrupción de datos. Y se ha oido decir eso de que Ext4 es aun muy nuevo, y lo de que yo me quedo de momento con Ext3 que es más seguro. Pues aquí voy a contar un par de cosas sobre este divertido asunto.

En el Mundo Real (tm), todos los sistemas operativos retrasan las escrituras por cuestion de rendimiento. Eso quiere decir que cuando un programa usa write(), o llama a close(), y la llamada retorna, el SO no garantiza que se haya escrito nada en el disco. Los datos están en memoria y se escribirán físicamente más o menos tarde, pero si antes de eso hay un corte de luz los datos se pierden y punto.

Así es como funcionan todos los SO. El journaling y las técnicas usadas por ZFS y btrfs y demás compañía están orientadas solo a garantizar la integridad del sistema de archivos, no que los datos hayan llegado al disco o no. De hecho, todos los sistemas de archivos modernos, como Ext4, XFS, ZFS o btrfs, utilizan "Delayed Allocation", lo cual significa que retrasan la escritura de datos al disco muchísimo más de lo normal, incluso minutos. Si una aplicación quiere tener una garantía inequívoca de que los datos están en el disco -y a la mayoría de aplicaciones no le importa-, POSIX dice que ha de utilizar fsync() (o la función sync_file_range() en Linux, que es mucho más potente). Cuando esa llamada al sistema finaliza, entonces si que se tiene la garantía de que los datos están en el disco (y solo cuando finaliza, pues si se va la luz mientras se está ejecutando, tambien se pueden perder datos)

El problema principal ha surgido a partir de algo que suelen hacer muchos programas para actualizar un archivo. Leen el archivo, modifican los datos, escriben los nuevos datos a un archivo aparte, y finalmente hacen un rename("archivo_con_datos_modificados", "archivo"), y de ese modo actualizan el archivo de configuración "atomicamente". Pero al renombrar el archivo se crea un nuevo inodo, que no tiene bloques de datos asociados -están en la memoria-, por lo tanto si antes de escribirse los datos se va la luz, el archivo aparecerá con 0 bytes, es decir, vacío. Esto es especialmente notable con Ext4 y todos los sistemas de archivo que utilizan delayed allocation, pero tambien existe el riesgo con Ext3, aunque el riesgo es mucho menor porque cada 5 segundos se sincronizan los datos de la memoria con el disco.

La solución "correcta" es usar fsync(). Pero la presión de los desarrolladores y de la enorme cantidad de programas que no usan fsync() y de Linus -que se ha puesto de su parte, diciendo al estilo británico que para bien o para mal las costumbres han de ser ley- ha forzado a añadir a Ext4 un hack que consiste en hacer un fsync() implícito cuando un programa usa rename() o truncate() (otro de los casos problemáticos). Así, los programas que no hacen fsync() no dejarán archivos de tamaño cero por ahí. Pero esto tambien hará que los programas que ejecutan esas funciones frecuentemente, como rsync, pierdan rendimiento. Pero como es lo que la gente ha pedido, toca fastidiarse. Eso si, otros SO no usan este truco, asi que esas aplicaciones tendrán problemas en esos otros sistemas.

Como se puede ver, no es que Ext4 "corrompa datos", sino un comportamiento de las aplicaciones que Ext4 tan solo ha puesto de manifiesto. Muy cierto es, sin embargo, que de cara al usuario, lo que se encuentra ante un reinicio son archivos sin datos, y eso es un problema muy grave del que se libra en gran medida usando Ext3 y su sync() implícito cada 5 segundos, y no es menos cierto que para Ext4 ese hack es la solución más práctica al problema. Pero de ahí a los titulares que se han leido de corrupcion de datos por ahí va un mundo. De hecho, a pesar de este asunto, Ext4 es mucho más seguro que Ext3, debido a que activa las "barreras" por defecto. Y eso es otro asunto muy interesante....

Al igual que el sistema cachea las escrituras en RAM, el disco retrasa en su propio cache (16-32 MB en los más modernos) las escrituras. Además no necesariamente escribe los datos en orden de llegada. Los sistemas de archivo a menudo envían al disco peticiones de escritura con caracter síncrono, es decir, que cuando la funcion retorne se tenga la garantía de que los datos están en el disco. Pero cuando no utilizan barreras -que es una especie de fsync() interno del kernel, solo que a nivel de bloques y peticiones al disco en vez de a nivel de descriptores de archivo-, tan solo creen tener esa garantía, y continuan mandado datos a pesar de todo. En caso de corte de luz, esos datos pueden llegar a perderse, o escribirse en diferente orden, y generar corrupción. En cambio, con barreras se utilizan unos comandos especiales del disco para asegurarse de que los datos fueron grabados físicamente, y por tanto en caso de corte de luz no hay posibilidad de sorpresas.

Pues bien, como Ext3 por defecto no usa barreras (fundamentalmente, porque afectan una barbaridad al rendimiento) un corte luz puede corromper el sistema de archivos, a pesar del journaling. Se trata de un margen de posibilidad muy pequeño, prácticamente despreciable, pero existente. De hecho, varias personas de Red Hat, Suse, etc, han manifestado en reiteradas ocasiones que activar las barreras por defecto ha supuesto para sus empresas una reducción notable de "casos extraños de corrupción". Ext4 sin embargo activa el soporte de barreras por defecto (sin afectar demasiado al rendimiento). Esto, sin embargo, no ha salido a relucir en ninguno de esos artículos y comentarios que acusaban a Ext4 de corromper datos y que recomiendan Ext3 como opción sólida.

13 comentarios:

  1. No veas lo que aprendo cuando leo tu blog, tío. Y me acabo de acordar de lo mucho que me comí la cabeza cuando perdía datos en XFS por los cortes de luz. A causa de eso volví a poner mi /home en ext3...

    ResponderEliminar
  2. Resumen: La culpa es de kde xDDDDDDDD

    ResponderEliminar
  3. Ese hack va como opción en ext4 o es necesario parchear para no usarlo y tener el comportamiento posix?

    Linux no debería adaptarse a las malas programaciones, son los programadores los que deben hacer programas decentes.

    ResponderEliminar
  4. deabru: Ese hack está por defecto, para desactivarlo hay que montar ext4 con una opción especial. Tambien se ha incorporado a Ext3 y a btrfs, y otros sistemas de archivos tambien lo van a incorporar.

    Si, la culpa es de los programas, pero siendo realistas es imposible arreglar todos los programas, mientras que este hack soluciona todos esos problemas con muy poco esfuerzo.

    ResponderEliminar
  5. Un par de preguntas (bueno tres):

    - los que tengan una SAI o similar, esta opción no dará mucha seguridad "extra", ¿verdad?

    - ¿Cuál es la opción de montaje para eliminar esta feature (o bug, no lo tengo claro :P )?

    - Y la última sin mucha relación, pero bueno: Si has formateado una partición en ext4 con journal, se puede desactivar el journal mediante opción al montar? ¿O usando e2tunefs?

    Muchas gracias por los artículos, se aprende un huevo de ellos. Sigue así.

    ResponderEliminar
  6. Anónimo11:06 a. m.

    Conocí este blog gracias al podcast El Amuleto de Yendor y nunca podré dejar de estar agradecido a Carlos y Nacho, este es el mejor blog que he leído en español sobre Linux, todas las entradas son increíblemente didácticas. Sólo quería decir eso y felicitarte sinceramente por tu trabajo. Enhorabuena y sigue adelante.

    ResponderEliminar
  7. cruzki: Los que tenga SAI les da lo mismo, por supuesto...

    La opción para desactivar estos cambios es "auto_da_alloc". Lo de quitar el journal parece que se suele hacer al crear el sistema de archivos, no se si el tune2fs lo quitará...

    ResponderEliminar
  8. Brillante, la verdad es que me encanta leer tu blog, y como ya dijeron mas arriba, se aprende un monton leyendo tus post.
    Saludos

    ResponderEliminar
  9. Pero si el hack está aplicado por defecto, como dice duego calleja, pq ocurrieron los mencionados problemas?

    ResponderEliminar
  10. Anónimo9:38 a. m.

    Interesante, creo que seguire usando ext3 por un tiempo, jeje.
    Videos de Mandria

    ResponderEliminar
  11. Una pregunta:

    comentas que los FS actuales retardan el volcado de datos a disco. Y comentas que cuando se renombra un fichero se crea un inodo.

    Primero: no entiendo por qué se crea un inodo en el caso que pones como ejemplo porque se supone que el inodo con ese nombre ya existe de antes ( porque se está editando ).

    Segundo: ¿ no debería hacerse la creación del inodo al mismo tiempo que se vuelcan los datos a BBDD ? No tiene mucho sentido crear inodos sin tener los datos fisicamente en disco ¿ no?

    Bueno, quizá (seguro ) no he entendido bien el artículo, pero si podeis echarme una mano, lo agradecería :-)

    ResponderEliminar
  12. Anónimo4:11 a. m.

    Pues a mi me pasó lo siguiente. Tuve mi portable hibernando durante unos 3 o 4 dias. Cada dia lo encendia, lo usaba, lo hibernaba y al final de los 4 días, el computador actuó de manera extraña y lo reinicie. Pues, ¡oh sorpresa! la máquina se negó a arrancar y la partición se perdió con todo mi trabajo. Vaya usted a saber EXT4 que bug tiene o que cosa terrible le falta. Esto me ocurrió en KUbuntu 9.04. Ahora, tuve que reinstalar todo, y por supuesto EXT3. Usaré EXT4 en 4 años o algo asi.

    ResponderEliminar
  13. Anónimo6:10 a. m.

    yo nunca he perdido datos ni en ext3 ni en reiserfs, sin embargo,no he migrado a ext4.

    Lo que sí, antes tenía una partición ntfs y una vfat(ya no las tengo), y a pesar que nunca usé ntfs-3g y vfat estaba siempre en modo ro, constantemente perdía datos en ella.

    Es raro, porque tengo computador como desde el 2000, sin embago, tengo linux desde el 2005, y las perdidas de datos coinciden más o menos con el momento en el que empece a usar linux.

    ¿pueden estar relacionadas las cosas?

    ResponderEliminar