Últimos Cambios |
||
Blog personal: El hilo del laberinto |
Última Actualización: 13 de julio de 2007 - Viernes
En el documento ZFS y errores explico que ZFS mantiene cierto nivel de replicación de la información más crítica del "zpool", con el fin de mantener su integridad aunque ocurran errores en un "zpool" sin redundancia, o si la redundancia es insuficiente para corregir todos los errores que han aparecido.
En concreto, la versión actual de ZFS almacena dos copias de los metadatos de cada "dataset", y tres copias de los metadatos globales a todo el "zpool". Versiones inminentes de ZFS permitirán grabar hasta tres copias de todos los metadatos, así como de los propios datos del usuario (configurable por "dataset"). Además, se intentan almacenar dichas copias en discos duros distintos del "zpool" y, si no es posible, en un mismo disco duro pero "alejadas" unas de otras.
Por tanto, aún con corrupción de datos, fallos de discos duros, etc., es posible navegar por los directorios y ver las características de los ficheros (nombre, tamaño, fechas, permisos, etc), aunque los datos en sí de los ficheros se hayan destruidos. Al mantenerse la integridad del "zpool", podemos borrar esos ficheros dañados y recuperarlos de una copia de seguridad previa, sabiendo que la estructura lógica del almacenamiento sigue siendo consistente. Explico cómo identificar los ficheros dañados en el documento anterior.
En este documento vamos a ver un ejemplo de esta capacidad de supervivencia.
El primer paso consiste en crear dos ficheros de un gigabyte, que utilizaremos como unidades de almacenamiento. A continuación creamos un "zpool" nuevo, con dichas unidades:
[root@tesalia z]# mkfile 1G file1 [root@tesalia z]# mkfile 1G file2 [root@tesalia z]# ls -la total 2097164 drwxr-xr-x 2 root root 241 2007-07-13 19:57 . drwxrwxrwt 8 root sys 7368 2007-07-13 19:57 .. -rw------T 1 root root 1073741824 2007-07-13 19:57 file1 -rw------T 1 root root 1073741824 2007-07-13 19:57 file2 [root@tesalia z]# zpool create prueba /tmp/z/file1 /tmp/z/file2 [root@tesalia z]# zpool list NAME SIZE USED AVAIL CAP HEALTH ALTROOT [...] prueba 1.98G 80K 1.98G 0% ONLINE - [root@tesalia z]#
Aquí podemos comprobar que se ha creado un "zpool" llamado "prueba", de dos gigabytes de capacidad. Como hemos creado el "zpool" a partir de dos ficheros de un gigabyte cada uno, es evidente que no estamos utilizando ningún sistema de redundancia como replicación, RAIDZ o similar.
Copiemos ahora algo "gordo", para ocupar sitio:
[root@tesalia z]# cp -a /usr/local /prueba [...] cp: cannot create directory `/prueba/local/BerkeleyDB.4.4': No space left on device cp: preserving permissions for `/prueba/local': No space left on device [root@tesalia z]# zpool list NAME SIZE USED AVAIL CAP HEALTH ALTROOT [...] prueba 1.98G 1.95G 31.9M 98% ONLINE -
La copia no se completa porque mi directorio "/usr/local/" mide más de 2 gigabytes. Vemos que todavía quedan unos 32 megabytes libres, pero ese espacio está reservado por ZFS para poder hacer cosas como borrar un fichero, o cambiarle su nombre, ya que se trata de un sistema de ficheros "COW" ("Copy On Write").
ZFS es muy agresivo cacheando información en memoria, así que el primer paso será exportar y reimportar de nuevo el "zpool" para asegurarnos de que la caché está vacía, y que todos los datos que pidamos tendrán que ir a buscarse al disco duro. A continuación, antes de hacer nada más, vamos a corromper uno de los ficheros que se usan como almacenaje del "zpool":
[root@tesalia z]# zpool export prueba [root@tesalia z]# zpool import -d /tmp/z/ prueba [root@tesalia z]# ls -la total 2097164 drwxr-xr-x 2 root root 241 2007-07-13 19:57 . drwxrwxrwt 8 root sys 7744 2007-07-13 20:13 .. -rw------T 1 root root 1073741824 2007-07-13 20:12 file1 -rw------T 1 root root 1073741824 2007-07-13 20:12 file2 [root@tesalia z]# dd if=/dev/zero of=file1 bs=1024 count=1048576 seek=0 conv=notrunc 1048576+0 records in 1048576+0 records out 1073741824 bytes (1.1 GB) copied, 36.707 s, 29.3 MB/s [root@tesalia z]# ls -la total 2097164 drwxr-xr-x 2 root root 241 2007-07-13 19:57 . drwxrwxrwt 8 root sys 7750 2007-07-13 20:17 .. -rw------T 1 root root 1073741824 2007-07-13 20:17 file1 -rw------T 1 root root 1073741824 2007-07-13 20:12 file2
Según esto, hemos corrompido la mitad de nuestro "zpool". Pero si vamos al "zpool" en cuestión y empezamos a movernos por él y a listar directorios, vemos que todo funciona con normalidad:
[root@tesalia z]# cd /prueba/local/ [root@tesalia local]# ls -la total 28 drwxr-xr-x 15 root root 15 2007-06-21 12:10 . drwxr-xr-x 3 root sys 3 2007-07-13 20:01 .. drwxr-xr-x 13 root root 13 2007-05-08 18:26 apache drwxr-xr-x 7 root root 7 2007-07-02 13:26 apache2 drwxr-xr-x 7 root root 7 2006-02-22 20:16 apr drwxr-xr-x 3 root root 3 2006-02-06 23:23 doc drwxr-xr-x 25 root root 80 2007-06-30 16:29 include drwxr-xr-x 2 root root 135 2007-06-28 21:14 info drwxrwsr-x 13 root mailman 13 2006-02-24 18:35 mailman drwxr-xr-x 27 root root 28 2007-05-29 21:15 man drwxr-xr-x 2 root root 3 2006-10-13 15:49 php drwxr-xr-x 27 root root 27 2007-06-04 15:40 share drwxr-xr-x 9 root root 10 2007-03-26 19:01 ssl drwxr-xr-x 2 root root 13 2007-04-23 12:57 svc drwxr-xr-x 3 root root 3 2007-07-06 19:59 var [root@tesalia local]# cd ssl/lib [root@tesalia lib]# ls -la total 1555 drwxr-xr-x 3 root root 11 2007-06-12 23:20 . drwxr-xr-x 9 root root 10 2007-03-26 19:01 .. -r--r--r-- 1 root root 5287 2006-01-30 19:14 fips_premain.c -r--r--r-- 1 root root 68 2007-01-16 15:06 fips_premain.c.sha1 lrwxrwxrwx 1 root root 14 2007-07-13 20:02 libcrypto.so -> libcrypto.so.0 lrwxrwxrwx 1 root root 18 2007-07-13 20:02 libcrypto.so.0 -> libcrypto.so.0.9.7 -r-xr-xr-x 1 root root 1282624 2007-03-26 19:01 libcrypto.so.0.9.7 lrwxrwxrwx 1 root root 11 2007-07-13 20:02 libssl.so -> libssl.so.0 lrwxrwxrwx 1 root root 15 2007-07-13 20:02 libssl.so.0 -> libssl.so.0.9.7 -r-xr-xr-x 1 root root 236060 2007-03-26 19:01 libssl.so.0.9.7 drwxr-xr-x 2 root root 3 2006-10-03 01:13 pkgconfig
Todo parece funcionar correctamente, pero veamos qué nos dice ZFS:
Aquí podemos ver como se están detectando errores en el almacenamiento que hemos corrompido, pero los datos de directorio se obtienen de la otra copia. El efecto neto es que a medida que nos movemos por los directorios, se van encontrando errores y se corrigen automáticamente aprovechando la otra réplica, todo de forma transparente y automática.[root@tesalia share]# zpool status prueba pool: prueba state: ONLINE status: One or more devices has experienced an unrecoverable error. An attempt was made to correct the error. Applications are unaffected. action: Determine if the device needs to be replaced, and clear the errors using 'zpool clear' or replace the device with 'zpool replace'. see: http://www.sun.com/msg/ZFS-8000-9P scrub: none requested config: NAME STATE READ WRITE CKSUM prueba ONLINE 0 0 4 /tmp/z//file1 ONLINE 0 0 4 /tmp/z//file2 ONLINE 0 0 0 errors: No known data errors
El detalle importante es el "No known data errors" al final del comando, que nos indica que ZFS está soportando bastante bien el maltrado. Recordemos que estamos corrompiendo un "zpool" al que no hemos especificado ningún tipo de redundancia tipo "mirror" o "RAIDZ".
Veamos qué ocurre ahora si intentamos leer un fichero:
[root@tesalia man1]# pwd /prueba/local/share/man/man1 [root@tesalia man1]# md5sum * 2>&1|head 28740479fdd82fcb9d99b756e4fa3d5c a2p.1 506e2e0f5f0297f29e11127c08a06366 autoconf.1 b68a482641c513f34124a6f0c0c6bf8c autoheader.1 f118e9c0e995d672ba6ab7c6c1cbba9d autom4te.1 md5sum: autoreconf.1: I/O error 36da8eb47268b03b448524e3f65fb2c2 autoscan.1 md5sum: autoupdate.1: I/O error md5sum: base64.1: I/O error 52f444040eb2060fdcc89a01f68d3634 basename.1 md5sum: bison.1: I/O error
Como vemos, algunos ficheros se leen correctamente y otros no, dependiendo de si se han grabado en un disco duro u otro. ZFS trocea los ficheros en bloques de 128Kbytes, por defecto, y los graba en un disco duro u otro en función del espacio libre que tenga cada disco, o su nivel de actividad, con una eurística bastante sofisticada. En ficheros grandes (varios megas), es muy normal que los diferentes bloques de 128Kbytes acaben en discos distintos, pero ficheros tan cortitos como los manuales "man", que miden menos de 128Kbytes y, por tanto, solo ocupan un bloque, se graban por completo en un disco duro u otro.
Veamos ahora qué nos dice ZFS:
[root@tesalia man1]# zpool status prueba pool: prueba state: ONLINE status: One or more devices has experienced an error resulting in data corruption. Applications may be affected. action: Restore the file in question if possible. Otherwise restore the entire pool from backup. see: http://www.sun.com/msg/ZFS-8000-8A scrub: none requested config: NAME STATE READ WRITE CKSUM prueba ONLINE 0 0 1.23K /tmp/z//file1 ONLINE 0 0 1.23K /tmp/z//file2 ONLINE 0 0 0 errors: 166 data errors, use '-v' for a list
Ahora ZFS ya no puede ocultar los errores, ya que el "zpool" no contiene redundancia a nivel de datos de usuario. Podemos salvar los ficheros contenidos completamente en el componente que no hemos corrompido, pero los ficheros grandes, al estar repartidos entre los dos, requerirán recuperar el backup.
Lo que es importante ver, es que en todo momento ZFS ha mantenido la integridad de todas sus estructuras críticas, como los directorios, los nombres de los ficheros e información interna muy delicada, como la lista de sectores libres, la descripción de los "datasets" contenidos en el "zpool", etc. Aquellos de nosotros que hemos perdido grandes segmentos de un árbol de directorios por un único sector dañado en un mal sitio, agradecemos el esfuerzo que ZFS despliega para protegernos al máximo.
Es de señalar, aunque resulte evidente, que estos niveles de redundancia a nivel de metadatos son independientes de la redundancia implícita configurada en el "zpool". Es decir, si nuestro "zpool" está formado por dos discos en espejo, habrá realmente 4 y 6 copias de los metadatos, en vez de 2 y 3.
Otro detalle interesante es que la versión actual de ZFS no protege los metadatos correspondientes a los enlaces simbólicos de más de 56 bytes. Ver bug 6516171 en OpenSolaris.
Más información sobre los OpenBadges
Donación BitCoin: 19niBN42ac2pqDQFx6GJZxry2JQSFvwAfS