Tengo varios TB de datos personales muy valiosos en un zpool al que no puedo acceder debido a la corrupción de datos. El grupo se configuró originalmente en 2009 en un sistema FreeBSD 7.2 que se ejecuta dentro de una máquina virtual VMWare en la parte superior de un sistema Ubuntu 8.04. FreeBSD VM todavía está disponible y funciona bien, solo el sistema operativo host ahora ha cambiado a Debian 6. Los discos duros se hacen accesibles a la VM invitada por medio de dispositivos SCSI genéricos VMWare, 12 en total.
Hay 2 piscinas:
- zpool01: 2x 4x 500GB
- zpool02: 1x 4x 160GB
El que funciona está vacío, el roto contiene todos los datos importantes:
[user@host~]$ uname -a
FreeBSD host.domain 7.2-RELEASE FreeBSD 7.2-RELEASE #0: \
Fri May 1 07:18:07 UTC 2009 \
root@driscoll.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64
[user@host ~]$ dmesg | grep ZFS
WARNING: ZFS is considered to be an experimental feature in FreeBSD.
ZFS filesystem version 6
ZFS storage pool version 6
[user@host ~]$ sudo zpool status
pool: zpool01
state: UNAVAIL
scrub: none requested
config:
NAME STATE READ WRITE CKSUM
zpool01 UNAVAIL 0 0 0 insufficient replicas
raidz1 UNAVAIL 0 0 0 corrupted data
da5 ONLINE 0 0 0
da6 ONLINE 0 0 0
da7 ONLINE 0 0 0
da8 ONLINE 0 0 0
raidz1 ONLINE 0 0 0
da1 ONLINE 0 0 0
da2 ONLINE 0 0 0
da3 ONLINE 0 0 0
da4 ONLINE 0 0 0
pool: zpool02
state: ONLINE
scrub: none requested
config:
NAME STATE READ WRITE CKSUM
zpool02 ONLINE 0 0 0
raidz1 ONLINE 0 0 0
da9 ONLINE 0 0 0
da10 ONLINE 0 0 0
da11 ONLINE 0 0 0
da12 ONLINE 0 0 0
errors: No known data errors
Pude acceder a la piscina hace un par de semanas. Desde entonces, tuve que reemplazar casi todo el hardware de la máquina host e instalar varios sistemas operativos host.
Mi sospecha es que una de estas instalaciones de sistema operativo escribió un gestor de arranque (o lo que sea) en una (¿la primera?) De las unidades de 500 GB y destruyó algunos metadatos de zpool (o lo que sea), lo que significa que esto es solo una idea muy vaga y ese tema no es exactamente mi lado fuerte ...
Hay muchos sitios web, blogs, listas de correo, etc. sobre ZFS. Publico esta pregunta aquí con la esperanza de que me ayude a reunir suficiente información para un enfoque sensato, estructurado, controlado, informado y bien informado para recuperar mis datos, y espero ayudar a alguien más en la misma situación.
El primer resultado de búsqueda al buscar en Google 'zfs recovery' es el capítulo de Solución de problemas y recuperación de datos de ZFS de la Guía de administración de Solaris ZFS. En la primera sección de modos de falla de ZFS , dice en el párrafo 'Datos corruptos de ZFS':
La corrupción de datos siempre es permanente y requiere una consideración especial durante la reparación. Incluso si los dispositivos subyacentes se reparan o reemplazan, los datos originales se pierden para siempre.
Algo desalentador.
Sin embargo, el segundo resultado de la búsqueda de Google es el blog de Max Bruning y allí, leí
Recientemente, recibí un correo electrónico de alguien que tenía 15 años de videos y música almacenados en un grupo de 10 TB de ZFS que, después de una falla de energía, se volvió defectuoso. Él desafortunadamente no tenía una copia de seguridad. Estaba usando ZFS versión 6 en FreeBSD 7 [...] Después de pasar aproximadamente 1 semana examinando los datos en el disco, pude restaurar básicamente todos.
y
En cuanto a que ZFS pierda sus datos, lo dudo. Sospecho que sus datos están allí, pero necesita encontrar la forma correcta de obtenerlos.
(Eso suena mucho más como algo que quiero escuchar ...)
Primer paso : ¿Cuál es exactamente el problema?
¿Cómo puedo diagnosticar por qué exactamente se informa que el zpool está dañado? Veo que hay zdb que no parece estar documentado oficialmente por Sun u Oracle en ninguna parte de la web. Desde su página de manual:
NAME
zdb - ZFS debugger
SYNOPSIS
zdb pool
DESCRIPTION
The zdb command is used by support engineers to diagnose failures and
gather statistics. Since the ZFS file system is always consistent on
disk and is self-repairing, zdb should only be run under the direction
by a support engineer.
If no arguments are specified, zdb, performs basic consistency checks
on the pool and associated datasets, and report any problems detected.
Any options supported by this command are internal to Sun and subject
to change at any time.
Además, Ben Rockwood ha publicado un artículo detallado y hay un video de Max Bruning hablando sobre esto (y mdb) en la Open Solaris Developer Conference en Praga el 28 de junio de 2008.
Ejecutar zdb como root en el zpool roto da el siguiente resultado:
[user@host ~]$ sudo zdb zpool01
version=6
name='zpool01'
state=0
txg=83216
pool_guid=16471197341102820829
hostid=3885370542
hostname='host.domain'
vdev_tree
type='root'
id=0
guid=16471197341102820829
children[0]
type='raidz'
id=0
guid=48739167677596410
nparity=1
metaslab_array=14
metaslab_shift=34
ashift=9
asize=2000412475392
children[0]
type='disk'
id=0
guid=4795262086800816238
path='/dev/da5'
whole_disk=0
DTL=202
children[1]
type='disk'
id=1
guid=16218262712375173260
path='/dev/da6'
whole_disk=0
DTL=201
children[2]
type='disk'
id=2
guid=15597847700365748450
path='/dev/da7'
whole_disk=0
DTL=200
children[3]
type='disk'
id=3
guid=9839399967725049819
path='/dev/da8'
whole_disk=0
DTL=199
children[1]
type='raidz'
id=1
guid=8910308849729789724
nparity=1
metaslab_array=119
metaslab_shift=34
ashift=9
asize=2000412475392
children[0]
type='disk'
id=0
guid=5438331695267373463
path='/dev/da1'
whole_disk=0
DTL=198
children[1]
type='disk'
id=1
guid=2722163893739409369
path='/dev/da2'
whole_disk=0
DTL=197
children[2]
type='disk'
id=2
guid=11729319950433483953
path='/dev/da3'
whole_disk=0
DTL=196
children[3]
type='disk'
id=3
guid=7885201945644860203
path='/dev/da4'
whole_disk=0
DTL=195
zdb: can't open zpool01: Invalid argument
Supongo que el error 'argumento inválido' al final ocurre porque el zpool01 en realidad no existe: no ocurre en el zpool02 de trabajo, pero tampoco parece haber más resultados ...
OK, en esta etapa, probablemente sea mejor publicar esto antes de que el artículo sea demasiado largo.
Tal vez alguien pueda darme algún consejo sobre cómo avanzar desde aquí y mientras espero una respuesta, miraré el video, repasaré los detalles de la salida de zdb anterior, leeré el artículo de Bens e intentaré averiguar qué es qué...
20110806-1600 + 1000
Actualización 01:
Creo que he encontrado la causa raíz: Max Bruning tuvo la amabilidad de responder a un correo electrónico mío muy rápidamente, pidiendo la salida de zdb -lll
. En cualquiera de los 4 discos duros en la 'buena' raidz1 mitad del grupo, la salida es similar a lo que publiqué anteriormente. Sin embargo, en las primeras 3 de las 4 unidades en la mitad 'rota', los zdb
informes failed to unpack label
para las etiquetas 2 y 3. La cuarta unidad en el grupo parece estar bien, zdb
muestra todas las etiquetas.
Buscar en Google ese mensaje de error muestra esta publicación . Desde la primera respuesta a esa publicación:
Con ZFS, son 4 etiquetas idénticas en cada vdev físico, en este caso, un solo disco duro. L0 / L1 al comienzo de vdev y L2 / L3 al final de vdev.
Las 8 unidades del grupo son del mismo modelo, Seagate Barracuda 500GB . Sin embargo, recuerdo que comencé el grupo con 4 unidades, luego una de ellas murió y Seagate la reemplazó bajo garantía. Más tarde, agregué otras 4 unidades. Por esa razón, los identificadores de unidad y firmware son diferentes:
[user@host ~]$ dmesg | egrep '^da.*?: <'
da0: <VMware, VMware Virtual S 1.0> Fixed Direct Access SCSI-2 device
da1: <ATA ST3500418AS CC37> Fixed Direct Access SCSI-5 device
da2: <ATA ST3500418AS CC37> Fixed Direct Access SCSI-5 device
da3: <ATA ST3500418AS CC37> Fixed Direct Access SCSI-5 device
da4: <ATA ST3500418AS CC37> Fixed Direct Access SCSI-5 device
da5: <ATA ST3500320AS SD15> Fixed Direct Access SCSI-5 device
da6: <ATA ST3500320AS SD15> Fixed Direct Access SCSI-5 device
da7: <ATA ST3500320AS SD15> Fixed Direct Access SCSI-5 device
da8: <ATA ST3500418AS CC35> Fixed Direct Access SCSI-5 device
da9: <ATA SAMSUNG HM160JC AP10> Fixed Direct Access SCSI-5 device
da10: <ATA SAMSUNG HM160JC AP10> Fixed Direct Access SCSI-5 device
da11: <ATA SAMSUNG HM160JC AP10> Fixed Direct Access SCSI-5 device
da12: <ATA SAMSUNG HM160JC AP10> Fixed Direct Access SCSI-5 device
Sin embargo, recuerdo que todas las unidades tenían el mismo tamaño. Mirando las unidades ahora, muestra que el tamaño ha cambiado para tres de ellas, se han reducido en 2 MB:
[user@host ~]$ dmesg | egrep '^da.*?: .*?MB '
da0: 10240MB (20971520 512 byte sectors: 255H 63S/T 1305C)
da1: 476940MB (976773168 512 byte sectors: 255H 63S/T 60801C)
da2: 476940MB (976773168 512 byte sectors: 255H 63S/T 60801C)
da3: 476940MB (976773168 512 byte sectors: 255H 63S/T 60801C)
da4: 476940MB (976773168 512 byte sectors: 255H 63S/T 60801C)
da5: 476938MB (976771055 512 byte sectors: 255H 63S/T 60801C) <--
da6: 476938MB (976771055 512 byte sectors: 255H 63S/T 60801C) <--
da7: 476938MB (976771055 512 byte sectors: 255H 63S/T 60801C) <--
da8: 476940MB (976773168 512 byte sectors: 255H 63S/T 60801C)
da9: 152627MB (312581808 512 byte sectors: 255H 63S/T 19457C)
da10: 152627MB (312581808 512 byte sectors: 255H 63S/T 19457C)
da11: 152627MB (312581808 512 byte sectors: 255H 63S/T 19457C)
da12: 152627MB (312581808 512 byte sectors: 255H 63S/T 19457C)
Por lo que parece, no fue una de las instalaciones del sistema operativo que 'escribió un gestor de arranque en una de las unidades' (como había supuesto antes), en realidad era la nueva placa base (un ASUS P8P67 LE ) que creaba un host de 2 MB área protegida al final de tres de las unidades que estropearon mis metadatos ZFS.
¿Por qué no creó un HPA en todas las unidades? Creo que esto se debe a que la creación de HPA solo se realiza en unidades más antiguas con un error que se corrigió más tarde mediante una actualización del BIOS del disco duro de Seagate: cuando todo este incidente comenzó hace un par de semanas, ejecuté SeaTools de Seagate para verificar si hay algo físicamente mal con las unidades (todavía en el hardware antiguo) y recibí un mensaje que me decía que algunas de mis unidades necesitan una actualización del BIOS. Como ahora estoy tratando de reproducir los detalles exactos de ese mensaje y el enlace a la descarga de la actualización del firmware, parece que desde que la placa base creó el HPA, ambas versiones SeaTools DOS no pueden detectar los discos duros en cuestión, un rápido invalid partition
o algo similar parpadea cuando comienzan, eso es todo. Irónicamente, sí encuentran un conjunto de unidades Samsung.
(Me he saltado los detalles dolorosos, que consumen mucho tiempo y, en última instancia, son infructuosos de enredar en un shell FreeDOS en un sistema no conectado en red). Al final, instalé Windows 7 en una máquina separada para ejecutar SeaTools Windows versión 1.2.0.5. Solo un último comentario sobre SeaTools de DOS: no se moleste en intentar arrancarlos de forma independiente; en su lugar, invierta un par de minutos y cree una memoria USB de arranque con el increíble Ultimate Boot CD , que además de DOS SeaTools también le ofrece muchos otros herramientas útiles
Cuando se inicia, SeaTools para Windows muestra este cuadro de diálogo:
Los enlaces conducen al Verificador de número de serie (que por alguna razón está protegido por un captcha - mío era 'Usuarios invasivos') y un artículo de la base de conocimiento sobre la actualización del firmware. Probablemente haya más enlaces específicos para el modelo de disco duro y algunas descargas y demás, pero no seguiré ese camino por el momento:
No me apresuraré a actualizar el firmware de tres unidades a la vez que tienen particiones truncadas y son parte de un grupo de almacenamiento roto. Eso es pedir problemas. Para empezar, la actualización del firmware probablemente no se pueda deshacer, y eso podría arruinar irrevocablemente mis posibilidades de recuperar mis datos.
Por lo tanto, lo primero que haré a continuación es crear una imagen de las unidades y trabajar con las copias, por lo que hay un original al que volver si algo sale mal. Esto podría introducir una complejidad adicional, ya que ZFS probablemente notará que las unidades fueron intercambiadas (por medio del número de serie de la unidad u otro UUID o lo que sea), a pesar de que se trata de copias dd de bits exactos en el mismo modelo de disco duro. Además, el zpool ni siquiera está vivo. Chico, esto puede ser complicado.
Sin embargo, la otra opción sería trabajar con los originales y mantener las unidades duplicadas como copia de seguridad, pero probablemente me encuentre con la complejidad anterior cuando algo salga mal con los originales. Naa, no está bien.
Para limpiar los tres discos duros que servirán como reemplazos de imágenes para las tres unidades con el BIOS defectuoso en el grupo roto, necesito crear algo de espacio de almacenamiento para las cosas que están allí ahora, así que profundizaré la caja de hardware y ensamblar un zpool temporal de algunas unidades antiguas, que también puedo usar para probar cómo ZFS trata con el intercambio de unidades dd'd.
Esto podría tomar un tiempo...
20111213-1930 + 1100
Actualización 02:
Esto tomó un tiempo de hecho. Pasé meses con varias cajas de computadoras abiertas en mi escritorio con varias cantidades de pilas de discos duros colgando y también dormí algunas noches con tapones para los oídos, porque no podía apagar la máquina antes de acostarme, ya que estaba ejecutando una operación crítica prolongada . Sin embargo, ¡finalmente prevalecí! :-) También he aprendido mucho en el proceso y me gustaría compartir ese conocimiento aquí para cualquier persona en una situación similar.
Este artículo ya es mucho más largo de lo que cualquiera con un servidor de archivos ZFS fuera de acción tiene tiempo para leer, así que entraré en detalles aquí y crearé una respuesta con los hallazgos esenciales más abajo.
Cavé profundamente en la obsoleta caja de hardware para armar suficiente espacio de almacenamiento para mover las cosas de las unidades individuales de 500 GB a las que se reflejaron las unidades defectuosas. También tuve que extraer algunos discos duros de sus estuches USB, para poder conectarlos directamente a través de SATA. Hubo algunos problemas más, no relacionados, y algunas de las unidades antiguas comenzaron a fallar cuando las volví a poner en acción que requerían un reemplazo de zpool, pero omitiré eso.
Consejo: En algún momento, hubo un total de aproximadamente 30 discos duros involucrados en esto. Con tanto hardware, es de gran ayuda tenerlos apilados correctamente; los cables que se sueltan o el disco duro que se cae de su escritorio seguramente no ayudará en el proceso y pueden causar más daños a la integridad de sus datos.
Pasé un par de minutos creando algunos accesorios de disco duro de cartón improvisados que realmente ayudaron a mantener las cosas ordenadas:
Irónicamente, cuando conecté los discos viejos por primera vez, me di cuenta de que hay un viejo zpool allí que debo haber creado para probar con una versión anterior de algunos, pero no todos los datos personales que faltan, así que mientras la pérdida de datos fue algo reducido, esto significaba un desplazamiento adicional de un lado a otro de los archivos.
Finalmente, reflejé las unidades problemáticas en las unidades de respaldo, las usé para el zpool y dejé las originales desconectadas. Las unidades de respaldo tienen un firmware más nuevo, al menos SeaTools no informa de ninguna actualización de firmware requerida. Hice la duplicación con un simple dd de un dispositivo a otro, por ejemplo
sudo dd if=/dev/sda of=/dev/sde
Creo que ZFS nota el cambio de hardware (por algún UUID del disco duro o lo que sea), pero no parece importarle.
Sin embargo, el zpool todavía estaba en el mismo estado, réplicas insuficientes / datos dañados.
Como se menciona en el artículo de HPA Wikipedia mencionado anteriormente, la presencia de un área protegida de host se informa cuando Linux arranca y puede investigarse usando hdparm . Hasta donde yo sé, no hay una herramienta hdparm disponible en FreeBSD, pero en este momento, tenía FreeBSD 8.2 y Debian 6.0 instalados como sistema de arranque dual, así que arranqué en Linux:
user@host:~$ for i in {a..l}; do sudo hdparm -N /dev/sd$i; done
...
/dev/sdd:
max sectors = 976773168/976773168, HPA is disabled
/dev/sde:
max sectors = 976771055/976773168, HPA is enabled
/dev/sdf:
max sectors = 976771055/976773168, HPA is enabled
/dev/sdg:
max sectors = 976771055/976773168, HPA is enabled
/dev/sdh:
max sectors = 976773168/976773168, HPA is disabled
...
Entonces, el problema obviamente era que la nueva placa base creó un HPA de un par de megabytes al final de la unidad que 'ocultó' las dos etiquetas superiores ZFS, es decir, impidió que ZFS las viera.
Jugar con la HPA parece un negocio peligroso. Desde la página de manual de hdparm, parámetro -N:
Get/set max visible number of sectors, also known as the Host Protected Area setting.
...
To change the current max (VERY DANGEROUS, DATA LOSS IS EXTREMELY LIKELY), a new value
should be provided (in base10) immediately following the -N option.
This value is specified as a count of sectors, rather than the "max sector address"
of the drive. Drives have the concept of a temporary (volatile) setting which is lost on
the next hardware reset, as well as a more permanent (non-volatile) value which survives
resets and power cycles. By default, -N affects only the temporary (volatile) setting.
To change the permanent (non-volatile) value, prepend a leading p character immediately
before the first digit of the value. Drives are supposed to allow only a single permanent
change per session. A hardware reset (or power cycle) is required before another
permanent -N operation can succeed.
...
En mi caso, el HPA se elimina así:
user@host:~$ sudo hdparm -Np976773168 /dev/sde
/dev/sde:
setting max visible sectors to 976773168 (permanent)
max sectors = 976773168/976773168, HPA is disabled
y de la misma manera para las otras unidades con un HPA. Si obtiene la unidad incorrecta o algo sobre el parámetro de tamaño que especifique no es plausible, hdparm es lo suficientemente inteligente como para saber:
user@host:~$ sudo hdparm -Np976773168 /dev/sdx
/dev/sdx:
setting max visible sectors to 976773168 (permanent)
Use of -Nnnnnn is VERY DANGEROUS.
You have requested reducing the apparent size of the drive.
This is a BAD idea, and can easily destroy all of the drive's contents.
Please supply the --yes-i-know-what-i-am-doing flag if you really want this.
Program aborted.
Después de eso, reinicié la máquina virtual FreeBSD 7.2 en la que se había creado originalmente el zpool y el estado de zpool informó un grupo de trabajo nuevamente. ¡HURRA! :-)
Exporté el grupo en el sistema virtual y lo volví a importar en el sistema host FreeBSD 8.2.
Algunas actualizaciones de hardware más importantes, otro intercambio de placa base, una actualización del conjunto de ZFS a ZFS 4/15, una limpieza exhaustiva y ahora mi zpool consta de 8x1TB más 8x500GB de piezas raidz2:
[user@host ~]$ sudo zpool status
pool: zpool
state: ONLINE
scrub: none requested
config:
NAME STATE READ WRITE CKSUM
zpool ONLINE 0 0 0
raidz2 ONLINE 0 0 0
ad0 ONLINE 0 0 0
ad1 ONLINE 0 0 0
ad2 ONLINE 0 0 0
ad3 ONLINE 0 0 0
ad8 ONLINE 0 0 0
ad10 ONLINE 0 0 0
ad14 ONLINE 0 0 0
ad16 ONLINE 0 0 0
raidz2 ONLINE 0 0 0
da0 ONLINE 0 0 0
da1 ONLINE 0 0 0
da2 ONLINE 0 0 0
da3 ONLINE 0 0 0
da4 ONLINE 0 0 0
da5 ONLINE 0 0 0
da6 ONLINE 0 0 0
da7 ONLINE 0 0 0
errors: No known data errors
[user@host ~]$ df -h
Filesystem Size Used Avail Capacity Mounted on
/dev/label/root 29G 13G 14G 49% /
devfs 1.0K 1.0K 0B 100% /dev
zpool 8.0T 3.6T 4.5T 44% /mnt/zpool
Como última palabra, me parece que los grupos de ZFS son muy, muy difíciles de matar. Los chicos de Sun que crearon ese sistema tienen todos los motivos para llamarlo la última palabra en los sistemas de archivos. ¡El respeto!