mdadm repara un solo fragmento/sector

mdadm repara un solo fragmento/sector

Quiero construir un NAS usando mdadm para RAID y btrfs para la detección de bitrot. Tengo una configuración bastante básica, que combina 3 discos de 1 TB con mdadm en un RAID5 y además btrfs.

Sé que mdadm no puede reparar bitrot. Sólo puede decirme cuando hay discrepancias pero no sabe qué datos son correctos y cuáles defectuosos. Cuando le digo a mdadm que repare mi md0 después de simular bitrot, siempre reconstruye la paridad. Btrfs utiliza sumas de verificación para saber qué datos son defectuosos, pero no puede repararlos porque no puede ver la paridad.

Sin embargo, puedo ejecutar una limpieza btrfs y leer el syslog para obtener el desplazamiento de los datos que no coincidieron con su suma de comprobación. Luego puedo traducir este desplazamiento a un disco y un desplazamiento en ese disco, porque conozco el desplazamiento inicial de datos de md0 (2048 * 512), el tamaño del fragmento (512K) y el diseño (simétrico a la izquierda). El diseño significa que en mi primera capa la paridad está en el tercer disco, en la segunda capa en el segundo disco y en la tercera capa en el primer disco.

Combinando todos estos datos y algunos btrfs más sobre el conocimiento del formato de disco, puedo calcular exactamente qué parte de qué disco es el defectuoso. Sin embargo, no puedo encontrar una manera de decirle a mdadm que repare este fragmento específico.

Ya escribí un script que intercambia la paridad y el fragmento defectuoso usando el comando dd, luego inicia una reparación con mdadm y luego los intercambia nuevamente, pero esta no es una buena solución y realmente me gustaría que mdadm marque este sector como malo y no lo vuelvas a usar. Como empezó a pudrirse, hay muchas posibilidades de que vuelva a hacerlo.

Mi pregunta es:¿Hay alguna manera de decirle a mdadm que repare un solo fragmento (que no es la paridad) y posiblemente incluso marque un sector del disco como defectuoso? ¿Quizás creando un error de lectura io?

(Y sé que ZFS puede hacer todo esto por sí solo, pero no quiero usar memoria ECC)

Editar:esteLa pregunta/respuesta trata sobre cómo btrfs RAID6 es inestable y cómo ZFS es mucho más estable/utilizable. Eso no responde a mi pregunta sobre cómo reparar un único fragmento defectuoso conocido con mdadm.

Respuesta1

No puedo encontrar una manera de decirle a mdadm que repare este fragmento específico.

Esto se debe a que cuando hay una corrupción silenciosa de los datos, md no tiene suficiente información para saber qué bloque está dañado silenciosamente.

Te invito a leer miresponda a la pregunta 4 ("¿Por qué mdcontinúa usando un dispositivo con datos no válidos?") aquí, que explica esto con más detalle.

Para empeorar las cosas para el diseño propuesto,Si un bloque de paridad sufre una corrupción silenciosa de los datos, ¡la capa Btrfs superior no puede verlo! Cuando falla un disco con el bloque de datos correspondiente y usted intenta reemplazarlo, md utilizará la paridad corrupta y dañará irreversiblemente sus datos. Sólo cuando ese disco falle Btrfs reconocerá la corrupción, pero ya habrá perdido los datos.

Esto se debe a que md no lee bloques de paridad a menos que la matriz esté degradada.


Entonces, ¿hay alguna manera de decirle a mdadm que repare un solo fragmento (que no es la paridad) y posiblemente incluso marcar un sector del disco como defectuoso? ¿Quizás creando un error de lectura io?

Para los sectores defectuosos que el disco duro descubrió por sí mismo, md puede solucionarlo fácilmente porque md identifica el sector defectuoso.

Técnicamente puedes crear un sector defectuoso con hdparm --make-bad-sector, pero ¿cómo sabes qué disco tiene el bloque afectado por la corrupción silenciosa de datos?

Considere este ejemplo simplificado:

Fórmula de paridad:PARITY = DATA_1 + DATA_2

+--------+--------+--------+
| DATA_1 | DATA_2 | PARITY |
+--------+--------+--------+
|      1 |      1 |      2 | # OK
+--------+--------+--------+

Ahora corrompamos cada uno de los bloques silenciosamente con un valor de 3:

+--------+--------+--------+
| DATA_1 | DATA_2 | PARITY |
+--------+--------+--------+
|      3 |      1 |      2 | # Integrity failed – Expected: PARITY = 4
|      1 |      3 |      2 | # Integrity failed – Expected: PARITY = 4
|      1 |      1 |      3 | # Integrity failed – Expected: PARITY = 2
+--------+--------+--------+

Si no tuviera la primera tabla para mirar, ¿cómo sabría qué bloque está dañado?
No puedes estar seguro.

Esta es la razón por la que Btrfs y ZFS bloquean la suma de comprobación. Se necesita un poco más de espacio en disco, pero esta información adicional permite al sistema de almacenamiento determinar qué bloque se encuentra.

DeArtículo del blog de Jeff Bonwick "RAID-Z":

Cada vez que lee un bloque RAID-Z, ZFS lo compara con su suma de comprobación. Si los discos de datos no arrojaron la respuesta correcta, ZFS lee la paridad y luego realiza una reconstrucción combinatoria para determinar qué disco devolvió datos incorrectos.

Para hacer esto con Btrfs en md, tendría que intentar recalcular cada bloque hasta que la suma de verificación coincida en Btrfs, un proceso que requiere mucho tiempo y que no presenta una interfaz sencilla para el usuario/script.


Sé que ZFS puede hacer todo esto por sí solo, pero no quiero usar memoria ECC

Ni ZFS ni Btrfs sobre md dependen o siquiera conocen la memoria ECC. La memoria ECC solo detecta daños silenciosos en los datos de la memoria, por lo que es independiente del sistema de almacenamiento.

He recomendado ZFS sobre Btrfs para RAID-5 y RAID-6 (análogo a ZFS RAID-Z y RAID-Z2, respectivamente) antes en¿Btrfs sobre mdadm raid6?yDispositivo fallido en md RAID cuando ATA deja de responder, pero me gustaría aprovechar esta oportunidad para resumir algunas ventajas más de ZFS:

  • Cuando ZFS detecta una corrupción silenciosa de los datos, se corrige automática e inmediatamente en el acto sin ninguna intervención humana.
  • Si necesita reconstruir un disco completo, ZFS solo "regenerará" los datos reales en lugar de ejecutarlos innecesariamente en todo el dispositivo de bloque.
  • ZFS es una solución todo en uno para volúmenes lógicos y sistemas de archivos, lo que la hace menos compleja de administrar que Btrfs además de md.
  • RAID-Z y RAID-Z2 son confiables y estables, a diferencia
    • Btrfs en md RAID-5/RAID-6, que solo ofrece detección de errores en bloques de datos corruptos silenciosamente (además, los bloques de paridad corruptos silenciosamente pueden pasar desapercibidos hasta que sea demasiado tarde) y no hay una manera fácil de corregir errores, y
    • Btrfs RAID-5/RAID-6, que "tiene varios errores graves de pérdida de datos".
  • Si corrompiera silenciosamente un disco completo con ZFS RAID-Z2, no perdería ningún dato, mientras que en md RAID-6,De hecho, perdí 455.681 inodos..

Respuesta2

Encontré una manera de crear un error de lectura para mdadm.

Con dmsetup puedes crear dispositivos lógicos a partir de tablas.

Los dispositivos se crean cargando una tabla que especifica un destino para cada sector (512 bytes)

De:página de manual

En estas tablas puede especificar compensaciones que deberían devolver un error de IO, por ejemplo:

0 4096 linear /dev/sdb 0
4096 1 error
4097 2093055 linear /dev/sdb 4097

Esto crea un dispositivo (1 GB) con un error en el desplazamiento 4096*512.

información relacionada