El tl;dr: ¿cómo haría para arreglar un bloque defectuoso en 1 disco en una matriz RAID1?
Pero lea todo esto para conocer lo que ya he probado y los posibles errores en mis métodos. Intenté ser lo más detallado posible y realmente espero recibir comentarios.
Esta es mi situación: tengo dos discos de 2 TB (mismo modelo) configurados en una matriz RAID1 administrada por mdadm
. Hace aproximadamente 6 meses noté el primer bloque defectuoso cuando SMART lo informó. Hoy noté más y estoy tratando de solucionarlo.
Esta página CÓMOParece ser el único artículo al que todos se vinculan para corregir bloques defectuosos que SMART informa. Es una gran página, llena de información, sin embargo, está bastante desactualizada y no aborda mi configuración particular. Así es como mi configuración es diferente:
- En lugar de un disco, estoy usando dos discos en una matriz RAID1. Un disco informa errores mientras que el otro está bien. El CÓMO está escrito pensando en un solo disco, lo que plantea varias preguntas como "¿uso este comando en el dispositivo de disco o en el dispositivo RAID"?
- Estoy usando GPT, que fdisk no admite. He estado usando gdisk en su lugar y espero que me brinde la misma información que necesito.
Entonces, vayamos al grano. Esto es lo que he hecho, sin embargo, no parece estar funcionando. No dude en volver a verificar mis cálculos y método para detectar errores. Los errores de informe del disco son /dev/sda:
# smartctl -l selftest /dev/sda
smartctl 5.42 2011-10-20 r3458 [x86_64-linux-3.4.4-2-ARCH] (local build)
Copyright (C) 2002-11 by Bruce Allen, http://smartmontools.sourceforge.net
=== START OF READ SMART DATA SECTION ===
SMART Self-test log structure revision number 1
Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error
# 1 Short offline Completed: read failure 90% 12169 3212761936
Con esto, deducimos que el error reside en LBA 3212761936. Siguiendo el CÓMO, uso gdisk para encontrar el sector de inicio que se usará más adelante para determinar el número de bloque (ya que no puedo usar fdisk ya que no admite GPT):
# gdisk -l /dev/sda
GPT fdisk (gdisk) version 0.8.5
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Disk /dev/sda: 3907029168 sectors, 1.8 TiB
Logical sector size: 512 bytes
Disk identifier (GUID): CFB87C67-1993-4517-8301-76E16BBEA901
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 3907029134
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 3907029134 1.8 TiB FD00 Linux RAID
Usando tunefs
encuentro que el tamaño del bloque es 4096
. Usando esta información y el cálculo del HOWTO, concluyo que el bloque en cuestión es ((3212761936 - 2048) * 512) / 4096 = 401594986
.
Luego, el CÓMO me dirige a debugfs
ver si el bloque está en uso (uso el dispositivo RAID ya que necesita un sistema de archivos EXT, este fue uno de los comandos que me confundió ya que, al principio, no sabía si debía usar / dev/sda o /dev/md0):
# debugfs
debugfs 1.42.4 (12-June-2012)
debugfs: open /dev/md0
debugfs: testb 401594986
Block 401594986 not in use
Entonces el bloque 401594986 es un espacio vacío, debería poder escribir sobre él sin problemas. Sin embargo, antes de escribirlo, trato de asegurarme de que, efectivamente, no se pueda leer:
# dd if=/dev/sda1 of=/dev/null bs=4096 count=1 seek=401594986
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000198887 s, 20.6 MB/s
Si el bloque no se pudiera leer, no esperaría que esto funcionara. Sin embargo, lo hace. Repito usando /dev/sda
, /dev/sda1
, /dev/sdb
, /dev/sdb1
, /dev/md0
y +-5 en el número de bloque para buscar alrededor del bloque defectuoso. Todo funciona. Me encojo de hombros y sigo adelante y comprometo la escritura y sincronización (uso /dev/md0 porque pensé que modificar un disco y no el otro podría causar problemas, de esta manera ambos discos sobrescriben el bloque defectuoso):
# dd if=/dev/zero of=/dev/md0 bs=4096 count=1 seek=401594986
1+0 records in
1+0 records out
4096 bytes (4.1 kB) copied, 0.000142366 s, 28.8 MB/s
# sync
Esperaría que al escribir en el bloque defectuoso los discos reasignen el bloque a uno bueno; sin embargo, al ejecutar otra prueba SMART se muestra de manera diferente:
# 1 Short offline Completed: read failure 90% 12170 3212761936
Volvamos al punto 1. Básicamente, ¿cómo arreglaría un bloque defectuoso en 1 disco en una matriz RAID1? Seguro que no he hecho algo correctamente...
Gracias por su tiempo y paciencia.
EDITAR 1:
Intenté ejecutar una prueba SMART larga, y el mismo LBA resultó malo (la única diferencia es que informa que queda un 30% en lugar de un 90%):
SMART Self-test log structure revision number 1
Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error
# 1 Extended offline Completed: read failure 30% 12180 3212761936
# 2 Short offline Completed: read failure 90% 12170 3212761936
También he usado badblocks con el siguiente resultado. El resultado es extraño y parece tener un formato incorrecto, pero intenté probar los números generados como bloques, pero debugfs da un error.
# badblocks -sv /dev/sda
Checking blocks 0 to 1953514583
Checking for bad blocks (read-only test): 1606380968ne, 3:57:08 elapsed. (0/0/0 errors)
1606380969ne, 3:57:39 elapsed. (1/0/0 errors)
1606380970ne, 3:58:11 elapsed. (2/0/0 errors)
1606380971ne, 3:58:43 elapsed. (3/0/0 errors)
done
Pass completed, 4 bad blocks found. (4/0/0 errors)
# debugfs
debugfs 1.42.4 (12-June-2012)
debugfs: open /dev/md0
debugfs: testb 1606380968
Illegal block number passed to ext2fs_test_block_bitmap #1606380968 for block bitmap for /dev/md0
Block 1606380968 not in use
No estoy seguro de adónde ir desde aquí. badblocks
Definitivamente encontré algo, pero no estoy seguro de qué hacer con la información presentada...
EDITAR 2
Más comandos e información.
Me siento como un idiota por olvidar incluir esto originalmente. Estos son los valores SMART para /dev/sda
. Tengo 1 Current_Pending_Sector y 0 Offline_Uncorrectable.
SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
1 Raw_Read_Error_Rate 0x002f 100 100 051 Pre-fail Always - 166
2 Throughput_Performance 0x0026 055 055 000 Old_age Always - 18345
3 Spin_Up_Time 0x0023 084 068 025 Pre-fail Always - 5078
4 Start_Stop_Count 0x0032 100 100 000 Old_age Always - 75
5 Reallocated_Sector_Ct 0x0033 252 252 010 Pre-fail Always - 0
7 Seek_Error_Rate 0x002e 252 252 051 Old_age Always - 0
8 Seek_Time_Performance 0x0024 252 252 015 Old_age Offline - 0
9 Power_On_Hours 0x0032 100 100 000 Old_age Always - 12224
10 Spin_Retry_Count 0x0032 252 252 051 Old_age Always - 0
11 Calibration_Retry_Count 0x0032 252 252 000 Old_age Always - 0
12 Power_Cycle_Count 0x0032 100 100 000 Old_age Always - 75
181 Program_Fail_Cnt_Total 0x0022 100 100 000 Old_age Always - 1646911
191 G-Sense_Error_Rate 0x0022 100 100 000 Old_age Always - 12
192 Power-Off_Retract_Count 0x0022 252 252 000 Old_age Always - 0
194 Temperature_Celsius 0x0002 064 059 000 Old_age Always - 36 (Min/Max 22/41)
195 Hardware_ECC_Recovered 0x003a 100 100 000 Old_age Always - 0
196 Reallocated_Event_Count 0x0032 252 252 000 Old_age Always - 0
197 Current_Pending_Sector 0x0032 100 100 000 Old_age Always - 1
198 Offline_Uncorrectable 0x0030 252 100 000 Old_age Offline - 0
199 UDMA_CRC_Error_Count 0x0036 200 200 000 Old_age Always - 0
200 Multi_Zone_Error_Rate 0x002a 100 100 000 Old_age Always - 30
223 Load_Retry_Count 0x0032 252 252 000 Old_age Always - 0
225 Load_Cycle_Count 0x0032 100 100 000 Old_age Always - 77
# mdadm -D /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Thu May 5 06:30:21 2011
Raid Level : raid1
Array Size : 1953512383 (1863.01 GiB 2000.40 GB)
Used Dev Size : 1953512383 (1863.01 GiB 2000.40 GB)
Raid Devices : 2
Total Devices : 2
Persistence : Superblock is persistent
Update Time : Tue Jul 3 22:15:51 2012
State : clean
Active Devices : 2
Working Devices : 2
Failed Devices : 0
Spare Devices : 0
Name : server:0 (local to host server)
UUID : e7ebaefd:e05c9d6e:3b558391:9b131afb
Events : 67889
Number Major Minor RaidDevice State
2 8 1 0 active sync /dev/sda1
1 8 17 1 active sync /dev/sdb1
Según una de las respuestas: parece que cambié seek
y skip
para dd
. Estaba usando buscar porque eso es lo que se usa con el CÓMO. El uso de este comando provoca dd
que se bloquee: # dd if=/dev/sda1 of=/dev/null bs=4096 count=1 skip=401594986
Usar bloques alrededor de ese (..84, ..85, ..87, ..88) parece funcionar bien, y usar /dev/sdb1 con 401594986
lecturas de bloque también está bien (como se esperaba ya que ese disco pasó la prueba SMART ). Ahora, la pregunta que tengo es: Al escribir sobre esta área para reasignar los bloques, ¿uso /dev/sda1
o /dev/md0
? No quiero causar ningún problema con la matriz RAID al escribir directamente en un disco y no actualizar el otro disco.
EDITAR 3
Escribir en el bloque produjo directamente errores en el sistema de archivos. Elegí una respuesta que resolvió el problema rápidamente:
# 1 Short offline Completed without error 00% 14211 -
# 2 Extended offline Completed: read failure 30% 12244 3212761936
Gracias a todos los que ayudaron. =)
Respuesta1
Todas estas respuestas de "empujar al sector" son, francamente, una locura. Corren el riesgo de dañar el sistema de archivos (posiblemente oculto). Si los datos ya no estuvieran, porque ese disco almacenaba la única copia, sería razonable. Pero hay una copia en perfecto estado en el espejo.
Sólo necesitas que mdraid frote el espejo. Notará el sector defectuoso y lo reescribirá automáticamente.
# echo 'check' > /sys/block/mdX/md/sync_action # use 'repair' instead for older kernels
Debe colocar el dispositivo correcto allí (por ejemplo, md0 en lugar de mdX). Esto llevará un tiempo, ya que lo hace con toda la matriz de forma predeterminada. En un kernel suficientemente nuevo, puede escribir números de sector en sync_min/sync_max primero, para limitarlo a solo una parte de la matriz.
Esta es una operación segura. Puedes hacerlo en todos tus dispositivos mdraid. De hecho, tudeberíahazlo en todos tus dispositivos mdraid, regularmente. Es probable que su distribución venga con un cronjob para manejar esto, ¿tal vez necesite hacer algo para habilitarlo?
Script para todos los dispositivos RAID del sistema
Hace un tiempo, escribí este script para "reparar" todos los dispositivos RAID del sistema. Esto fue escrito para versiones anteriores del kernel donde sólo la 'reparación' arreglaría el sector defectuoso; ahora basta con hacer la verificación (la reparación aún funciona bien en los kernels más nuevos, pero también vuelve a copiar/reconstruir la paridad, que no siempre es lo que se desea, especialmente en unidades flash)
#!/bin/bash
save="$(tput sc)";
clear="$(tput rc)$(tput el)";
for sync in /sys/block/md*/md/sync_action; do
md="$(echo "$sync" | cut -d/ -f4)"
cmpl="/sys/block/$md/md/sync_completed"
# check current state and get it repairing.
read current < "$sync"
case "$current" in
idle)
echo 'repair' > "$sync"
true
;;
repair)
echo "WARNING: $md already repairing"
;;
check)
echo "WARNING: $md checking, aborting check and starting repair"
echo 'idle' > "$sync"
echo 'repair' > "$sync"
;;
*)
echo "ERROR: $md in unknown state $current. ABORT."
exit 1
;;
esac
echo -n "Repair $md...$save" >&2
read current < "$sync"
while [ "$current" != "idle" ]; do
read stat < "$cmpl"
echo -n "$clear $stat" >&2
sleep 1
read current < "$sync"
done
echo "$clear done." >&2;
done
for dev in /dev/sd?; do
echo "Starting offline data collection for $dev."
smartctl -t offline "$dev"
done
Si desea hacerlo check
en lugar de repair
, entonces este primer bloque (no probado) debería funcionar:
case "$current" in
idle)
echo 'check' > "$sync"
true
;;
repair|check)
echo "NOTE: $md $current already in progress."
;;
*)
echo "ERROR: $md in unknown state $current. ABORT."
exit 1
;;
esac
Respuesta2
Acabo de tener prácticamente el mismo problema con una matriz RAID1. El sector defectuoso estaba justo al comienzo de una de las particiones: el sector 16 de /dev/sdb2. Seguí las instrucciones anteriores: después de verificar que el sistema de archivos no estaba utilizando el bloque lógico 2 y teniendo cuidado de obtener dd seek y skip de la manera correcta, puse a cero 1 bloque del sistema de archivos:
# dd if=/dev/zero of=/dev/md0 bs=4096 count=1 seek=2
¿Qué hizo esto? No solucionó el sector malo. Esto, ahora lo sé, se debe a que /dev/md0 no se asigna directamente a /dev/sdb2, ¡debe tener en cuenta el DESPLAZAMIENTO DE DATOS RAID! Más sobre esto a continuación. Lo que sí hizo fue un pequeño pero potencialmente devastador excremento en mi sistema de archivos. Resulta que el bloque lógico 2 de /dev/md0 contenía metadatos útiles del sistema de archivos y estaba bien en ambos discos, hasta que cagué enamboscopias escribiendo a /dev/md0. Afortunadamente, e2fsck -y /dev/md0 solucionó el problema (después de arrojar una cantidad alarmante de resultados) sin pérdida de datos aparente. Lección aprendida: si debugfs icheck dice "bloque no encontrado", no significa necesariamente que no se utilicen los sectores correspondientes.
Volviendo al desplazamiento de datos: use mdadm para encontrar el desplazamiento de esta manera:
# mdadm --examine /dev/sdb2
/dev/sdb2:
Magic : a92b4efc
Version : 1.2
Feature Map : 0x0
Array UUID : ef7934b9:24696df9:b89ff03e:b4e5a05b
Name : XXXXXXXX
Creation Time : Sat Sep 1 01:20:22 2012
Raid Level : raid1
Raid Devices : 2
Avail Dev Size : 1953241856 (931.38 GiB 1000.06 GB)
Array Size : 976620736 (931.38 GiB 1000.06 GB)
Used Dev Size : 1953241472 (931.38 GiB 1000.06 GB)
Data Offset : 262144 sectors
Super Offset : 8 sectors
State : clean
Device UUID : f3b5d515:446d4225:c2191fa0:9a9847b8
Update Time : Thu Sep 6 12:11:24 2012
Checksum : abb47d8b - correct
Events : 54
Device Role : Active device 0
Array State : AA ('A' == active, '.' == missing)
En este caso, el desplazamiento de datos es de 262144 sectores de 512 bytes. Si agrega desde /dev/md0 y lo compara con datos de la partición sin formato con un desplazamiento de 131072K, encontrará que coinciden. Entonces, en mi caso, el bloque lógico 2 (sectores 16--23) de /dev/sdb2 ni siquiera está en el sistema de archivos; están en el superbloque RAID, sobre el cual puedes leer aquí: https://raid.wiki.kernel.org/index.php/RAID_superblock_formats- para la versión 1.2, consta de 256 bytes + 2 bytes por dispositivo en la matriz, todos comenzando con 4096 bytes, por lo que en mi caso, no se utilizó el sector defectuoso. Los sectores correspondientes de /dev/sdc2 (la otra mitad de la matriz RAID1) son cero, así que pensé que sería seguro hacer esto:
# dd if=/dev/zero of=/dev/sdb2 bs=4096 count=1 seek=2
¡Funcionó!
Respuesta3
Si ejecuta Debian, lo más probable es que tenga un trabajo en /etc/cron.d/mdadm. Esto se ejecutará /usr/share/mdadm/checkarray --cron --all --idle --quiet
el primer domingo de cada mes. Ejecútelo manualmente cuando obtenga errores de hardware incorregibles para acelerar la reescritura.
Respuesta4
Si tienes un sw-raid1 y escribes datos directamente a uno de los miembros, tendrás un raid corrupto inmediatamente. NO escriba datos en un sdaX o sdbX si son parte de un mdX. Si escribe en mdX, los datos se copiarán en ambas unidades, si lee desde mdX, se leerán los datos de una de las unidades.