Este artículo es una colección de notas tomadas a lo largo de años de trabajar con RAID. Es un recordatorio de comandos, así como de procedimientos de recuperación de desastres.
sfdisk -d /dev/hdb | sfdisk /dev/hdc
sgdisk /dev/sdX -R /dev/sdY sgdisk -G /dev/sdY
El primero comando copia la tabla de particiones del disco sdX al sdY. El segundo randomiza los GUID de cada partición del disco sdY, lo cual es imprescindible ya que serán usados en el mismo equipo.
Este procedimiento es sumamente importante en el caso de falla de un disco, para poder identificarlo fehacientemente y reemplazarlo. El número de serie indicado por estos comandos es el mismo impreso en la etiqueta del disco, y por lo tanto puede ser usado para hacer valer la garantía.
smartctl -i /dev/hdb hdparm -i /dev/hdb
Obviamente los discos deben ser idénticos. Se puede intentar hacer esto cuando hay algunos bad sectors (sectores malos o dañados) en el disco original, y se lo reemplaza por uno nuevo. Es probable que hecho esto no se pierda demasiada información en el disco final.
Ese nuevo disco puede ser luego usado para recrear el RAID como si fuera el original, ya que son idénticos (incluyendo los datos que se perdieron debido a que estaban sobre sectores dañados).
Lo mejor es utilizar el utilitario de recuperación dd_rescue (aptitude install ddrescue en Debian GNU/Linux). Es más rápido y más confiable que usar simplemente dd (descrito abajo):
dd_rescue -v /dev/sdA /dev/sdB
Donde sdA es el disco origen y sdB el destino. Es un proceso que tarda generalmente muchas horas, dependiendo del tamaño del disco y de la cantidad de bad sectors. Por ejemplo, para discos de 500GB es probable que tarde entre 4 y 6 horas, según lo mencionado.
Si no se dispone de este utilitario, se puede intentar con dd. En teoría debería funcionar, pero no es muy confiable dado que el disco origen suele estar plagado de problemas. Si se desea intentarlo, se puede usar la siguiente serie de parámetros:
dd if=/dev/sdA of=/dev/sdB bs=10240k conv=noerror,sync
Si se desea ver el progreso de copiado con dd, se debe usar el utilitario pv (aptitude install pv en Debian GNU/Linux):
dd if=/dev/sdA bs=10240k conv=noerror,sync | pv -c -b -r -t > /dev/sdB
Si hay demasiados sectores dañados, es redundante mencionar que probablemente el disco destino no sirva ya para ser agregado al RAID y sus datos se hayan perdido. De cualquier manera, si se está realizando esto es porque ya no queda más remedio (por ejemplo, en el caso de que hayan fallado dos discos en un RAID5, y se pretende tratar de recuperar el desastre). Bajo ciertas condiciones, y con un poco de ayuda del Supremo, quizá quede otra vez la unidad md en estado funcional.
mdadm --create /dev/md5 --level=5 --raid-devices=3 /dev/sda9 /dev/sdb9 /dev/sdc9
mdadm --detail /dev/md3 cat /proc/mdstat
mdadm --manage -a /dev/md3 /dev/hdd8
mdadm --misc -S /dev/md3
mdadm --assemble /dev/md3
sfdisk -d /dev/sdX | sfdisk /dev/sdN
Donde X es un disco preexistente funcional y N es el disco nuevo
mdadm --add /dev/md0 /dev/sdc1
mdadm --add /dev/md0 /dev/sde1 mdadm --grow /dev/md0 --raid-devices=4
Cuando termine de sincronizar, lo cual puede llevar varias horas dependiendo del tamaño del array, se debe extender el sistema de archivos a toda la unidad RAID:
resize_reiserfs /dev/md0 o bien: resize2fs /dev/md0
mdadm /dev/md0 --grow --raid-devices=2 --backup-file=/root/grow_md0.bak --add /dev/sdb5
mdadm /dev/md0 --grow --level=0 --raid-devices=2 --backup-file=/root/grow_md4.bak
echo raid0 > /sys/block/md0/md/level
mdadm -D /dev/md0
Primero se debe detener la unidad en cuestión:
mdadm --stop /dev/md127
Luego, ensamblarla con el nuevo nombre, cuidando de poner algo similar a lo que ya esté en mdadm.conf:
mdadm --assemble --update=name --name=srv01:4 /dev/md4 /dev/sda8 /dev/sdb8
Luego se debe agregar la información de esta unidad en el archivo mdadm.conf, lo que se obtiene con el comando
mdadm --examine --scan
La línea correspondiente a esta nueva unidad debe ser copiada al archivo mdadm.conf
Finalmente, se debe actualizar el archivo initrd.img:
update-initramfs -u
# mdadm.conf # # Please refer to mdadm.conf(5) for information about this file. # # by default, scan all partitions (/proc/partitions) for MD superblocks. # alternatively, specify devices to scan, using wildcards if desired. DEVICE partitions # auto-create devices with Debian standard permissions CREATE owner=root group=disk mode=0660 auto=yes # automatically tag new arrays as belonging to the local system HOMEHOST <system> # instruct the monitoring daemon where to send mail alerts MAILADDR root
mdadm --detail --scan >> /etc/mdadm/mdadm.conf
y verificar que haya quedado todo bien. Otro método para escanear todas las particiones en búsqueda de unidades md es:
mdadm --examine --brief --scan --config=partitions
mkinitrd -r /dev/md0 -o /boot/initrd.img-2.6.8-4-k7
En vez de usar para montar el dispositivo (p.ej. /dev/md0), conviene usar el UUID del sistema de archivos, de la siguiente manera:
# /etc/fstab: static file system information. # # <file system> <mount point> <type> <options> <dump> <pass> proc /proc proc defaults 0 0 # /dev/md0 UUID=80dd4e01-3bcb-40a9-858f-84f222c7fb76 / reiserfs notail 0 1 # /dev/md2 UUID=a675b65b-2468-4ce0-b9b8-a18e18ad982e /tmp reiserfs defaults 0 2 # /dev/md3 UUID=df777ce0-1adf-481b-b4cd-ee9995226671 /usr reiserfs defaults 0 2 # /dev/md4 UUID=16a357e5-9733-4eea-9294-0fadb2160883 /var reiserfs defaults 0 2 # /dev/md5 UUID=c7cba866-7042-4cad-9d35-7dfcf177a164 /home reiserfs defaults 0 2 # /dev/md1 UUID=3a5e831d-8458-470c-a80a-88f481fb5944 none swap sw 0 0 /dev/scd0 /media/cdrom0 udf,iso9660 user,noauto 0 0
El UUID puede conocerse mediante alguno de los siguientes comandos:
ls -l /dev/disk/by-uuid/
o bien:
blkid /dev/md4
Para conocer más detalles del dispositivo:
vol_id /dev/md4
mdadm --assemble /dev/md0 --update=resync
Viernes por la noche. Argentina. Se cortó la luz, volviendo una hora más tarde. Luego de encender nuevamente el servidor, por alguna razón desconocida, se colgó. Al encenderlo por segunda vez, mdadm había desconectado uno de los dispositivos (sdb1) de la unidad md RAID5 (cuatro discos de 500GB, sin spare). Por lo tanto, entré en runlevel 1 y la agregué nuevamente con mdadm –add /dev/md0 /dev/sdb1, comenzando así a sincronizar. Esto fue a las 2300 hs, por lo que me fui a dormir. Cuando volví, descubrí con desagrado que luego de terminar la sincronización, otro de los discos había fallado, pero ahora mdadm había desconectado el primero así como a este otro (sdb1 y sdd1). Como sabía que la sincronización anterior había terminado y la unidad md no había sido usada, estimé que sería posible rescatar la unidad del desastre. Por lo tanto, leí toda la documentación que pude encontrar, y luego de nada más que unas tres o cuatro horas, comencé a trabajar. El procedimiento de rescate fue el siguiente:
mdadm --stop /dev/md0
mdadm --create /dev/md0 --assume-clean --level=5 --raid-devices=4 --metadata=1.2 /dev/sdb1 /dev/sdc1 missing /dev/sde1
“missing” reemplaza a la unidad que se va a agregar más tarde (sdd1); mdadm informará que las unidades ya pertenecen a un array, y preguntará si realmente se desea continuar con la creación del array, a lo que debe responderse que sí. Este paso reescribe los metadatos y crea un nuevo UUID, dejando todo como estaba e iniciando el array con tres dispositivos. Antes de recrear la unidad MD debe revisarse con CUIDADO que el estilo de metadata y el chunk size original son los que se va a usar para crearla. De otra manera se DESTRUYE el sistema de archivos. Por ejemplo, si la unidad preexistente tenía estilo de metadata 0.90 y se usa ahora 1.2, o si el chunk size era de 64k y ahora se usa 512k, ocurre la destrucción del sistema de archivos.
mdadm --stop /dev/md0
mdadm --assemble --update=resync -f /dev/md0 /dev/sdb1 /dev/sdc1 /dev/sde1
Si comienza a sincronizar, dejarlo que termine. Se puede ver si está sincronizando con:
cat /proc/mdstat
En mi caso no sincronizó, pero imagino que era lógico: el dispositivo estaba sincronizado, y si no hubiera sido así, se hubiera perdido todo con toda seguridad. Pero eso es un punto bueno de mdadm: si algo no está bien, detiene el array de manera que no se pierdan datos.
mdadm -a /dev/md0 /dev/sdd1
Hecho esto, el array sincronizará el nuevo dispositivo, proceso que llevará alrededor de 6 horas con estos cuatro discos de 500GB. Recomiendo encarecidamente no utilizar la unidad, ni el equipo (debería estar en runlevel 1), para evitar cualquier tipo de falla no esperada, y para acelerar el proceso de sincronización.
mdadm -D /dev/md0
reiserfsck /dev/md0
Los discos que fallaron deben revisarse con smartctl en búsqueda de cualquier inconveniente que indique que haya que reemplazar el o los discos. En el caso que se decida reemplazar ambos discos, debe hacerse de a un disco por vez y esperando en cada caso que la sincronización finalice, ya que no puede haber más de un disco fuera de servicio en una unidad RAID5.
Si bien en mi caso el rescate fue exitoso, no debe suponerse que sea algo habitual. La falla de más de un dispositivo de una misma unidad RAID5 provoca la pérdida completa de los datos, sin posibilidad de salvarlos de forma alguna. En el caso de que ocurra algo así, el array debe manejarse con el cuidado más completo, estando descansado, tranquilo y sin apuros. Es preferible perder unas horas más, que años de trabajo. Al comenzar el rescate, recomiendo elaborar un plan detallado, tratando de no olvidarse algún paso; luego de hecho esto, iniciar los trabajos. Este documento bien puede servir de base para ello.