Matemáticas de reconstrucción RAIDZ en ZFS: por qué una falla más puede ser fatal

¿Te fue útil?

Tu pager suena a las 02:13. Un disco murió. ZFS está resilverizando. Todo el mundo quiere una respuesta: “¿Cuánto tiempo hasta que estemos seguros?”
La mala noticia es que “seguro” no es una marca temporal. Es una curva de probabilidad que se vuelve fea justo cuando más necesitas que esté tranquila.

Las reconstrucciones RAIDZ no son solo cuestión de rendimiento. Son cuestión de tiempo de exposición, tasas de error y de cuántas maneras separadas puede traicionarte el almacenamiento
mientras estás ocupado arreglándolo. Las matemáticas no son difíciles. Las consecuencias lo son.

Términos que importan (y los que la gente usa mal)

RAIDZ no es “RAID-5 pero en ZFS”

RAIDZ es la disposición de paridad de ZFS. RAIDZ1 tolera una falla de disco en un vdev. RAIDZ2 tolera dos. RAIDZ3 tolera tres.
La tolerancia a fallos de un pool es la tolerancia a fallos de su vdev menos tolerante. Si tienes un vdev RAIDZ2 y además un vdev mirror,
el mirror no es el más débil. Pero un vdev RAIDZ1 en la mezcla sí lo es absolutamente.

Resilver vs rebuild

“Rebuild” es el término genérico en RAID. ZFS realiza un resilver: reconstruye los datos faltantes en un dispositivo de reemplazo.
El detalle clave: ZFS a menudo puede copiar solo los bloques asignados (no todo el disco), por lo que los resilvers pueden ser mucho más rápidos que las reconstrucciones clásicas.
Pero el vdev aún debe leer muchos datos para recomputar paridad y verificar checksums. Si tu pool está casi lleno, “solo bloques asignados”
se convierte en “la mayoría de los bloques”, y la diferencia pasa a ser teórica.

Scrub no es un backup ni es un resilver

Un scrub lee datos y verifica checksums, reparando corrupción usando redundancia. No te hace resistente a “ups, borramos prod”.
Pero los scrubs reducen la probabilidad de que la primera vez que descubras errores latentes de sector sea durante un resilver—cuando ya estás con un disco menos.

URE, errores latentes y por qué los números de los fabricantes mienten por omisión

URE significa “unrecoverable read error” (error de lectura irrecuperable). Los fabricantes publican una “tasa de error de bits irrecuperables” (UBER) como 10^-14 o 10^-15 bits.
La gente interpreta eso como “un error cada X TB” y deja de pensar. El riesgo real depende de:
cuántos bits lees durante el resilver, de cuántos discos lees, de lo que hace el firmware bajo estrés,
y de si has estado haciendo scrubs. El número publicado es un punto de partida, no una promesa.

Una cita para mantener en la mesa. La conocida idea de Richard Cook sobre sistemas complejos se resume a menudo así:
“El éxito en operaciones complejas se construye sobre la adaptación; el fracaso ocurre cuando las defensas se agotan.”
(idea parafraseada, Richard Cook)

Broma #1: Un resilver es como mudarte de departamento mientras el edificio está en llamas—técnicamente posible, pero descubrirás qué cajas son frágiles.

Datos interesantes y breve historia

  • ZFS se diseñó a mediados de los 2000 para tratar el almacenamiento como un sistema, no como un montón de dispositivos, integrando checksums de extremo a extremo y autocuración.
  • RAIDZ existe para evitar el “write hole” de RAID-5 integrando la actualización de paridad con grupos de transacciones copy-on-write.
  • Las primeras implementaciones de ZFS requerían mucha memoria; el meme “ZFS necesita toneladas de RAM” vino de la real necesidad de ARC en sistemas antiguos, no de superstición.
  • La realidad de sectores 4K lo cambió todo: desajustes de ashift (por ejemplo, discos 512e forzados a alineación de 512 bytes) pueden gravar permanentemente el rendimiento y los tiempos de reconstrucción.
  • La capacidad de los discos creció más rápido que el rendimiento; las ventanas de exposición al reconstruir se expandieron al pasar de cientos de GB a decenas de TB.
  • “Resilver solo usa espacio asignado” fue un cambio importante frente al RAID clásico, pero solo es tan bueno como tu fragmentación y ocupación.
  • Los checksums hicieron visible la corrupción silenciosa; el efecto desagradable es que descubres corrupción durante scrubs/resilvers, cuando el pool está estresado.
  • La expansión de RAIDZ llegó tarde comparado con los deseos de la gente; operacionalmente, eso significó muchos planes de “simplemente añade discos más grandes y reemplázalos uno por uno”.
  • Los números UBER de HDD empresariales mejoraron, pero el comportamiento del firmware bajo colas intensas aún puede producir timeouts que parecen “fallas aleatorias”.

Por qué una falla más puede ser fatal

En RAIDZ1, la muerte de un disco te deja en un estado donde cada bloque que necesita el disco faltante debe ser reconstruido desde los discos restantes.
Durante el resilver, estás degradado: no tienes redundancia. Una falla adicional—otra caída de disco, un problema de cable, un reset de controlador,
una oleada de UREs en el disco equivocado—puede convertir “resilver en curso” en “restaurar desde backups”, suponiendo que tengas backups.

RAIDZ2 te compra tiempo y opciones. No seguridad infinita, pero margen para respirar. Puedes sobrevivir a una segunda falla de dispositivo durante un resilver.
Y, más importante, puedes sobrevivir a un puñado de errores de lectura sin que el vdev se encierre en un rincón. La diferencia práctica es psicológica:
los ingenieros dejan de tomar decisiones apresuradas y arriesgadas.

Los modos de fallo no son independientes

Las matemáticas simpáticas asumen fallos independientes: un disco falla, otros discos tienen UREs aleatorios a tasas de fabricante, etc.
La realidad es más desordenada:

  • Los discos del mismo lote fallan cerca en el tiempo.
  • Las cargas de resilver son castigadoras: lecturas sostenidas, alta profundidad de cola y mucho IO aleatorio si el pool está fragmentado.
  • Los controladores y expanders se estresan; los cables marginales dejan de estar “bien”.
  • La térmica cambia: un ventilador caído o un chasis con mala ventilación convierten los rebuilds en una prueba de calentamiento.
  • Factores humanos: alguien ve “DEGRADED” y empieza a cambiar hardware como si fuera un juego de whack-a-mole.

La resiliencia que creías haber comprado con paridad a menudo se gasta en problemas “no de disco” durante la ventana de resilver.
Por eso la frase “una falla más puede ser fatal” es operativa, no poética.

Matemáticas de reconstrucción que realmente puedes usar

1) Tiempo de exposición: cuánto tiempo vives en riesgo

El modelo más simple y útil es: el riesgo aumenta con el tiempo que permaneces degradado. Si tu resilver toma 2 horas, estás expuesto 2 horas.
Si toma 2 días, estás expuesto 2 días. Los detalles importan, pero esto por sí solo explica por qué los vdevs RAIDZ1 sobredimensionados son una trampa.

Una estimación práctica para tiempo de resilver:

  • Datos a copiar ≈ bytes asignados en el vdev (no el pool), ajustados al alza por fragmentación y overhead de metadatos.
  • Ancho de banda efectivo ≈ mínimo de (ancho de lectura de disco, ancho de escritura al disco nuevo, cálculo de paridad del vdev, límites del controlador/expander y la interferencia de la carga del pool).
  • Tiempo de resilver ≈ datos-a-copiar / ancho-de-banda-efectivo.

Si estás al 80–90% de ocupación del pool, espera que “datos-a-copiar” esté incómodamente cerca de “todo el disco”, y espera que el IO aleatorio domine.
Por eso los operadores experimentados mantienen los pools RAIDZ por debajo de ~70–80% salvo razón poderosa para no hacerlo.

2) Matemáticas URE: el argumento clásico de “por qué murió RAID5 a escala” (y qué cambia ZFS)

El cálculo de bolsillo canónico es:
la probabilidad de al menos una URE al leer B bits es aproximadamente:
P ≈ 1 − (1 − p)B,
donde p es la probabilidad de URE por bit (p. ej., 10^-14).

Si lees muchos bits, P sube. Rápido. El error es tratar esto como evangelio en cualquier dirección:
“URE definitivamente ocurrirá” o “URE nunca ocurre en la práctica.” Ambas son holgazanas.

Lo que ZFS cambia:

  • ZFS verifica checksums, por lo que puede detectar datos malos en lugar de servirlos silenciosamente.
  • Con redundancia (RAIDZ2/3), ZFS a menudo puede reparar en torno a un sector malo usando paridad y otras copias.
  • Durante un resilver degradado en RAIDZ1, un error de lectura en el bloque equivocado puede volverse irrecuperable porque el disco faltante elimina tu último margen.

3) La realidad de “cuántos discos tengo que leer”

Durante un resilver RAIDZ, el sistema lee de todos los discos restantes en el vdev para reconstruir los datos faltantes. Eso significa:
cuanto más discos haya en el vdev, más lecturas agregadas, más oportunidades para:
timeouts, UREs y “este disco estaba bien hasta que le pediste leerlo todo.”

Los vdevs más anchos pueden ser geniales para rendimiento secuencial. También son geniales para concentrar riesgo durante el resilver.
RAIDZ2 con una anchura sensata tiende a ser la elección adulta para pools grandes de HDD.

4) Matemáticas de rendimiento que punzan: bloques pequeños y fragmentación

La velocidad del resilver no es solo “MB/s del disco”. Si tu conjunto de datos está lleno de bloques pequeños (bases de datos, VMs, buzones de correo),
ZFS hace más recorrido de metadatos, busca más y tu ancho de banda efectivo se colapsa.
Si tienes compresión, podrías leer menos del disco que del tamaño lógico de los datos. Si tienes deduplicación, podrías complicarte la vida de otras formas.

Las verdaderas matemáticas de reconstrucción son una mezcla:
ventana de exposición × probabilidad de fallas adicionales por unidad de tiempo × probabilidad de lecturas irrecuperables por dato leído.
No necesitas un doctorado para usarlo. Solo necesitas dejar de fingir que el tiempo de reconstrucción es constante.

Cómo funciona realmente el resilver en ZFS (y por qué a veces gana)

Copy-on-write y grupos de transacciones

ZFS es copy-on-write. Escribe bloques nuevos y luego actualiza punteros. Esto reduce la exposición al “write hole” porque ZFS puede mantener un estado consistente en disco
mediante grupos de transacciones. La paridad RAIDZ está integrada en esas escrituras.

Por qué “solo bloques asignados” es a la vez cierto y engañoso

ZFS resilveriza basado en lo que cree que está en uso, no en “cada LBA del disco.” Eso es bueno.
Pero hay tres trampas:

  • Ocupación del pool: si estás al 85% de uso, los bloques asignados son la mayor parte del disco.
  • Fragmentación: los bloques asignados están dispersos, por lo que el resilver se vuelve IO aleatorio.
  • Overhead de metadatos: bloques indirectos, spacemaps y gang blocks añaden lecturas y trabajo de CPU.

Resilver secuencial vs resilver de curación

ZFS puede realizar diferentes estilos de resilver dependiendo de la implementación y la situación (por ejemplo, comportamientos de escaneo secuencial),
pero operativamente debes asumir:
el resilver provoca lecturas sostenidas en el vdev, consume presupuesto de IO y degrada el rendimiento.
Si ejecutas una carga de producción pesada al mismo tiempo, estás eligiendo una ventana de exposición más larga.

Broma #2: El resilver más rápido es el que programas antes de que falle el disco—lamentablemente, los discos rechazan invitaciones de calendario.

Qué realmente enlentece un resilver

1) El pool está ocupado y ZFS es cortés

ZFS evita intencionalmente secuestrar todo el sistema. IO de resilver compite con el IO normal.
Eso es genial para los usuarios. Es terrible para “volver a redundancia lo antes posible.”
Puedes ajustarlo, pero hacerlo a ciegas puede empeorar la latencia de producción y causar timeouts que parecen fallos de hardware.

2) Un solo disco lento arrastra todo el vdev

Los vdevs RAIDZ se comportan como un equipo de remeros. Un remero está con resaca y todos giran en círculos.
Un disco marginal que no ha “fallado” puede crear un cuello de botella en las lecturas, provocando resilvers largos y más estrés.

3) Controladores, expanders y cableado

Las reconstrucciones son excelentes para exponer cosas que nunca probaste: un puerto SAS del expander defectuoso, un cable que está “bien” en reposo,
un bug de firmware del controlador o una backplane que se calienta y comienza a lanzar errores.
Si tus logs muestran resets de enlace durante el resilver, trátalo como un incidente de fiabilidad, no como un misterio de rendimiento.

4) Errores de ashift son para siempre

Si un pool se creó con el ashift equivocado, cada escritura está desalineada. Eso infla el IO y perjudica el tiempo de resilver.
No puedes arreglar ashift in situ. Lo solucionas reconstruyendo el pool correctamente. Por eso “solo crea un pool rápido” es una decisión que limita tu carrera.

5) La CPU no suele ser el cuello de botella—hasta que lo es

Las CPUs modernas normalmente manejan la paridad RAIDZ y checksums bien. Pero la compresión intensa, el cifrado y cargas de IOPS elevadas pueden cambiar eso.
Observa la CPU durante el resilver. Si está al 100%, tus discos están esperando por operaciones matemáticas.

Guion de diagnóstico rápido

Cuando un resilver es lento, no tienes tiempo para depuración artesana. Haz triage como si fuera una interrupción.
El objetivo es encontrar el único factor limitante que puedas cambiar rápidamente.

Primero: confirma el dominio de la falla y el radio real del impacto

  • ¿Está degradado un solo vdev o varios?
  • ¿El pool realmente está sirviendo errores, o solo reconstruyendo?
  • ¿Hay errores de checksum (datos malos) o solo errores de dispositivo (ruta mala)?

Segundo: identifica la clase de cuello de botella

  • Disco lento individual: un disco que muestra alta latencia / bajo ancho de banda.
  • Problema de bus/ruta: resets de enlace, errores SAS, timeouts, multipath inestable.
  • Contención por carga: IO de producción está ahogando al resilver.
  • Presión de CPU/memoria: compresión/cifrado o thrash de ARC que ralentizan todo.

Tercero: toma la acción correctiva de menor riesgo

  • Si un disco claramente se comporta mal, reemplázalo ahora en lugar de “esperar a ver”.
  • Si la ruta es inestable, arregla cableado/firmware antes de quemar más discos.
  • Si la carga de producción es el problema, limita la tasa de clientes, mueve cargas o programa una ventana de mantenimiento para priorizar el resilver.

La respuesta correcta suele ser aburrida: reduce la carga, deja que termine el resilver y luego haz un scrub.
La respuesta equivocada es tuning heroico hecho en un pool que ya está degradado.

Tareas prácticas: comandos, salidas, decisiones

A continuación hay tareas de campo que puedes ejecutar ahora mismo. Cada una incluye: comando, qué significa la salida y la decisión que tomas.
Hostnames, pools y dispositivos son ejemplos; ajústalos a tu entorno.

Task 1: Verificar salud del pool y estado de resilver

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: DEGRADED
status: One or more devices is currently being resilvered.
action: Wait for the resilver to complete.
  scan: resilver in progress since Fri Dec 26 02:20:17 2025
        3.12T scanned at 410M/s, 1.84T issued at 242M/s, 6.20T total
        1.84T resilvered, 29.68% done, 6:05:11 to go
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        DEGRADED     0     0     0
          raidz2-0                  DEGRADED     0     0     0
            sda                     ONLINE       0     0     0
            sdb                     ONLINE       0     0     2
            sdc                     ONLINE       0     0     0
            sdd                     ONLINE       0     0     0
            sde                     ONLINE       0     0     0
            sdf                     ONLINE       0     0     0
            sdg                     ONLINE       0     0     0
            sdh                     ONLINE       0     0     0
            replacing-1             DEGRADED     0     0     0
              sdi                   FAULTED      0     0     0  too many errors
              sdz                   ONLINE       0     0     0  (resilvering)

errors: No known data errors

Significado: “issued” es trabajo real hecho; “scanned” puede ser mayor. Los errores CKSUM en un disco superviviente (sdb) son una bandera roja.

Decisión: Si los errores CKSUM aumentan durante el resilver, trátalo como inestabilidad de medio o de la ruta; planifica reemplazar o recablear ese disco.

Task 2: Ver I/O por vdev para detectar un dispositivo lento

cr0x@server:~$ zpool iostat -v tank 5 3
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
--------------------------  -----  -----  -----  -----  -----  -----
tank                        92.1T  28.7T  1.02K   210   310M  52.1M
  raidz2-0                  92.1T  28.7T  1.02K   210   310M  52.1M
    sda                         -      -    120    25  38.5M  6.3M
    sdb                         -      -     11    24   1.2M  6.2M
    sdc                         -      -    121    25  38.7M  6.2M
    sdd                         -      -    122    24  38.8M  6.1M
    sde                         -      -    121    26  38.6M  6.4M
    sdf                         -      -    120    25  38.5M  6.3M
    sdg                         -      -    121    25  38.6M  6.2M
    sdh                         -      -    120    25  38.4M  6.1M
    sdz                         -      -    287    22  66.1M  5.9M
--------------------------  -----  -----  -----  -----  -----  -----

Significado: sdb está aportando casi nada de ancho de banda de lectura comparado con sus pares.

Decisión: Investiga sdb inmediatamente (SMART, cableado, ruta del controlador). Un disco “lento pero online” puede matar tu ventana de resilver.

Task 3: Ver eventos ZFS recientes por flaps de dispositivo

cr0x@server:~$ zpool events -v | tail -n 20
TIME                           CLASS
Dec 26 2025 02:14:03.129812000  sysevent.fs.zfs.dev_remove
    pool = tank
    vdev_path = /dev/sdi
    vdev_guid = 1234567890123456789
Dec 26 2025 02:16:44.410223000  sysevent.fs.zfs.config_sync
    pool = tank
Dec 26 2025 02:20:17.004901000  sysevent.fs.zfs.resilver_start
    pool = tank
    vdev_path = /dev/sdz

Significado: Confirma la línea temporal de remove/replace; útil para correlacionar con logs y acciones humanas.

Decisión: Si ves eventos repetidos de remove/add, trátalo como inestabilidad de la ruta (expander/cable/HBA) más que como “disco malo”.

Task 4: Confirmar qué piensa ZFS sobre los errores

cr0x@server:~$ zpool status -x
pool 'tank' is not healthy

Significado: Sigue degradado; no da matices, pero es una comprobación rápida para dashboards y runbooks.

Decisión: Úsalo solo para condiciones de limpieza de alertas después de revisar el estado detallado.

Task 5: Extraer SMART y contadores de errores del disco sospechoso

cr0x@server:~$ sudo smartctl -a /dev/sdb | egrep -i "Model|Serial|Reallocated|Pending|Offline_Uncorrectable|UDMA_CRC|Error|SMART overall"
Device Model:     WDC WD140EDGZ-11B2DA2
Serial Number:    9JH3K1AB
SMART overall-health self-assessment test result: PASSED
Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       0
Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       8
Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       8
UDMA_CRC_Error_Count    0x003e   200   199   000    Old_age   Always       -       3

Significado: Sectores pendientes/offline uncorrectable son malos; errores CRC sugieren cableado/backplane/HBA problemático.

Decisión: Sectores pendientes durante un resilver? Reemplaza el disco. CRCs en aumento? Reasienta/reemplaza el cable, revisa logs de expander/HBA.

Task 6: Ejecutar un test SMART corto (si puedes permitirlo)

cr0x@server:~$ sudo smartctl -t short /dev/sdb
Please wait 2 minutes for test to complete.
Test will complete after Fri Dec 26 03:01:42 2025

Significado: Un test corto puede detectar fallos evidentes rápidamente.

Decisión: Si el disco no puede completar un test corto o informa fallos de lectura, deja de debatir y reemplázalo.

Task 7: Vigilar logs del kernel por resets de enlace y timeouts

cr0x@server:~$ sudo dmesg -T | egrep -i "sas|scsi|reset|timeout|link|I/O error" | tail -n 12
[Fri Dec 26 02:44:18 2025] sd 5:0:7:0: [sdb] tag#913 FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_OK
[Fri Dec 26 02:44:18 2025] sd 5:0:7:0: [sdb] CDB: Read(16) 88 00 00 00 00 10 2a 3f 00 00 00 00 80 00 00 00
[Fri Dec 26 02:44:19 2025] sas: phy-7: reset complete
[Fri Dec 26 02:44:22 2025] sd 5:0:7:0: [sdb] Sense Key : Medium Error [current]
[Fri Dec 26 02:44:22 2025] sd 5:0:7:0: [sdb] Add. Sense: Unrecovered read error

Significado: Timeouts + errores de medio durante lecturas intensas son exactamente lo que induce un resilver.

Decisión: Errores de medio: reemplaza el disco. Resets de PHY repetidos en múltiples discos: sospecha del expander/HBA/cableado/firmware.

Task 8: Identificar si el pool está demasiado lleno (el resilver se arrastrará)

cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint -S used tank | head
NAME            USED  AVAIL  REFER  MOUNTPOINT
tank            92.1T  28.7T   128K  /tank
tank/vm         41.8T  28.7T  41.8T  /tank/vm
tank/backups    28.2T  28.7T  28.2T  /tank/backups
tank/home       13.4T  28.7T  13.4T  /tank/home

Significado: ~76% asignado. Manejable, pero si esto fuera 90%+, el dolor del resilver aumenta drásticamente.

Decisión: Si >80% usado, planea liberar espacio o añadir capacidad después del incidente; no normalices pools RAIDZ “casi llenos”.

Task 9: Comprobar fragmentación (un asesino silencioso del resilver)

cr0x@server:~$ zpool list -o name,alloc,free,frag,cap,health
NAME   ALLOC   FREE  FRAG  CAP  HEALTH
tank   92.1T  28.7T   41%  76%  DEGRADED

Significado: 41% de fragmentación convertirá “copiar bloques asignados” en muchas búsquedas.

Decisión: Frag alta + resilver lento: reduce carga, espera una ventana más larga; considera rediseño futuro (más vdevs, distinto recordsize, mantener pools menos llenos).

Task 10: Comprobar ashift (alineación) del vdev

cr0x@server:~$ zdb -C tank | egrep "vdev|ashift" | head -n 20
        vdev_tree:
            type: 'raidz'
            id: 0
            guid: 9876543210123456789
            ashift: 12
            nparity: 2

Significado: ashift 12 significa alineación 4K. Bueno para HDD/SSD modernos. ashift 9 en 4K-native/512e es un clásico error propio.

Decisión: Si ashift está mal, no intentes “tunear” para arreglarlo. Programa una migración adecuada a un pool creado correctamente.

Task 11: Confirmar recordsize / volblocksize para datasets clave (impacta layout y comportamiento de resilver)

cr0x@server:~$ zfs get -o name,property,value -s local recordsize,volblocksize tank/vm tank/home
NAME      PROPERTY     VALUE
tank/vm   volblocksize 16K
tank/home recordsize   128K

Significado: Zvols de VM a 16K pueden generar muchas búsquedas; dataset home a 128K es más amigable secuencialmente.

Decisión: Si los resilvers son crónicamente lentos en pools con muchas VMs, considera vdevs especiales (metadatos), más vdevs o mirrors para tiers de alta IOPS.

Task 12: Pausar trabajo competidor: localizar consumidores top de I/O

cr0x@server:~$ sudo iostat -x 5 2
Linux 6.5.0 (server)  12/26/2025  _x86_64_  (32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.41    0.00    6.32   18.77    0.00   62.50

Device            r/s     w/s   rkB/s   wkB/s  await  svctm  %util
sda             98.1    22.4  39512    6821   28.4   3.1   95.2
sdb             11.3    21.9   1290    6720  412.7  10.2   99.8
sdz            210.4    18.2  67711    5812   16.9   2.7   89.4

Significado: sdb tiene 400ms de await y 99.8% de util mientras realiza lecturas pequeñas. Ese es el remero con resaca.

Decisión: Si la latencia de un disco es extrema, no esperes a que “se recupere.” Reemplázalo o arregla su ruta; de lo contrario, tu resilver será un desastre en cámara lenta.

Task 13: Encontrar errores de checksum a nivel de dataset (corrupción silenciosa que sale a la luz)

cr0x@server:~$ zpool status -v tank | sed -n '/errors:/,$p'
errors: Permanent errors have been detected in the following files:

        tank/home@daily-2025-12-25:/documents/finance.xlsx

Significado: Tienes al menos un error permanente: ZFS no pudo reparar ese bloque desde la redundancia.

Decisión: Activa respuesta a incidentes: identifica propietarios de datos afectados, restaura desde backup/replicación de snapshots y reevalúa nivel de redundancia y cadencia de scrubs.

Task 14: Iniciar un scrub después del resilver (pasada de validación)

cr0x@server:~$ sudo zpool scrub tank
cr0x@server:~$ zpool status tank | egrep -A3 "scan:"
  scan: scrub in progress since Fri Dec 26 09:02:11 2025
        1.34T scanned at 620M/s, 410G issued at 190M/s, 120T total
        0B repaired, 0.34% done, 178:22:10 to go

Significado: El scrub es más lento en pools grandes; “repaired” quedándose en 0 es bueno, pero “to go” importa para planificar.

Decisión: Si el scrub revela errores nuevos, trátalo como inestabilidad continua de medios/ruta—no declares victoria porque el resilver terminó.

Tres micro-historias corporativas (anonimizadas, plausibles, dolorosas)

Micro-historia 1: El incidente causado por una suposición equivocada

Una empresa SaaS mediana tenía un único pool ZFS grande para “todo lo que no está en la base de datos.” Era RAIDZ1 porque alguien recordó
que RAIDZ2 “desperdicia demasiado espacio,” y las hojas de cálculo ganan discusiones.

Un disco falló un viernes por la noche. El on-call lo reemplazó y vio la barra de progreso del resilver. Se movía, lentamente.
El equipo supuso que el único riesgo era “otro disco tiene que fallar,” lo que parecía improbable durante el fin de semana.
Dejaron el pool sirviendo tráfico de producción completo porque “los clientes no pueden tener downtime.”

Doce horas después, ZFS empezó a loguear errores de checksum en otro disco. SMART parecía “PASSED,” así que el equipo lo descartó como ruido.
El resilver continuó. Entonces el segundo disco lanzó una serie de sectores ilegibles exactamente en los bloques necesarios para reconstruir datos del disco faltante.
RAIDZ1 no tenía paridad extra para resolverlo. El vdev falló con la suficiente fuerza como para que el pool dejara de ser fiable.

La suposición equivocada no fue “no fallará un segundo disco.” Fue más sutil: “si el pool sigue online, estamos bien.”
ZFS seguirá intentando hasta que no pueda. Online no es lo mismo que seguro.

Su recuperación fue una mezcla desordenada: restaurar desde backups en object-store para la mayor parte de datos, aceptar pérdida de datos de algunos clientes,
y pasar el siguiente mes reconstruyendo almacenamiento con RAIDZ2 y una política de scrubs más estricta. La lección del postmortem fue contundente:
“Tratamos la paridad como seguro y luego cancelamos la póliza durante la única semana en la que la necesitábamos.”

Micro-historia 2: La optimización que salió mal

Una plataforma interna de analítica tenía un pool ZFS respaldando una granja de VMs. Llegaron quejas de rendimiento: picos de latencia en escrituras,
stalls ocasionales durante snapshots. Un ingeniero bienintencionado afinó para throughput: vdevs RAIDZ más anchos (porque “más discos = más rápido”),
compresión agresiva en todo y recordsize más grande porque “IO grande es eficiente.”

Parecía bien en benchmarks. Las lecturas secuenciales volaban. Las quejas disminuyeron. Todos siguieron con su trabajo.
Seis meses después, un disco falló. El resilver fue glacial. No solo “horas,” sino “días,” a pesar de que el pool no estaba casi lleno.

El problema: la carga era en su mayoría pequeñas lecturas/escrituras aleatorias de VMs, con churn de metadatos y snapshots frecuentes.
El vdev ancho implicaba más discos participando en cada operación de reconstrucción. La compresión aumentó el trabajo de CPU durante el resilver
justo cuando el sistema ya hacía cálculo de paridad y verificación de checksums. Y el recordsize grande en datasets equivocados
incrementó la amplificación de escritura y la fragmentación con el tiempo.

Durante el largo resilver, un segundo disco empezó a hacer timeouts—no estaba muerto, solo lento y caliente. El controlador registró resets.
El equipo tuvo que limitar toda la clúster de VMs para dejar avanzar el resilver, lo que creó un incidente visible para clientes de todas formas.
Habían optimizado la ruta feliz y hecho la ruta de falla insoportable.

Después, rediseñaron: vdevs más pequeños y numerosos; RAIDZ2; tuning cuidadoso de datasets (las VMs tratadas distinto que almacenamiento bulk);
y una regla de que cualquier cambio de rendimiento debe incluir “qué pasa durante un resilver” como prueba de aceptación de primera clase.
La optimización no falló porque fuera estúpida. Falló porque ignoró las matemáticas de recuperación.

Micro-historia 3: La práctica aburrida pero correcta que salvó el día

Un equipo empresarial conservador gestionaba almacenamiento para una plataforma interna de archivos. Nada glamoroso: muchos documentos, artefactos de builds,
unos pocos datasets grandes que crecían de forma constante. Tenían reputación de decir “no” a atajos emocionantes.

Su diseño era deliberadamente poco llamativo: vdevs RAIDZ2 de anchura moderada, hot spares disponibles, tests SMART largos mensuales
y scrubs en un calendario acorde a su dominio de fallo. También mantenían un objetivo estricto de utilización: cuando los pools se acercaban,
el trabajo de expansión de capacidad se gestionaba y financiaba como cualquier otro requerimiento de producción.

Cuando un disco falló, el on-call siguió el runbook: confirmar que no había otros discos con CRC en aumento, reducir jobs batch no esenciales,
reemplazar el disco, vigilar el resilver y luego hacer un scrub. El resilver terminó en horas, no días, porque el pool tenía margen y baja fragmentación.

Una semana después, otro disco mostró sectores pendientes en aumento. Aún no había fallado. Lo reemplazaron de forma proactiva en una ventana de mantenimiento.
Sin outage. Sin drama. El “coste” fue algunos discos adicionales y algo de tiempo en calendario. Eso es barato.

Lo que los salvó no fue una bandera mágica de ZFS. Fue la disciplina de tratar el almacenamiento como un sistema que debe seguir siendo recuperable,
no solo rápido. Su práctica aburrida previno el incidente emocionante.

Errores comunes: síntoma → causa raíz → solución

1) El resilver está “atorado” en un porcentaje bajo

Síntoma: “resilver in progress… 2% done… time remaining: days” apenas cambia.

Causa raíz: Fragmentación severa, carga aleatoria intensa o un único disco lento arrastrando las tasas de lectura.

Solución: Identifica disco lento vía zpool iostat -v y iostat -x; reduce carga; reemplaza disco sospechoso; mantiene pools menos llenos a largo plazo.

2) Incremento de errores CKSUM en un disco “ONLINE” durante el resilver

Síntoma: zpool status muestra incrementos de CKSUM en un dispositivo superviviente.

Causa raíz: Errores reales de medio o (muy a menudo) ruta inestable: resets de enlace SAS, cable malo, problemas de expander.

Solución: Revisa dmesg por resets/timeouts; revisa contadores SMART CRC; reasienta/reemplaza cables; actualiza firmware del HBA; reemplaza disco si aparecen sectores pendientes/errores de medio.

3) El pool queda FAULTED durante la reconstrucción RAIDZ1

Síntoma: Tras un segundo problema “menor”, el pool queda inaccesible o reporta errores permanentes.

Causa raíz: RAIDZ1 no tenía margen; una URE o segunda falla de dispositivo/ruta hizo que algunos bloques sean irreconstruibles.

Solución: Restaura desde backups/snapshots; reconstruye con RAIDZ2 o mirrors; aumenta la cadencia de scrubs; deja de usar RAIDZ1 para vdevs HDD grandes en producción.

4) La reconstrucción es lenta solo en un chasis / shelf

Síntoma: Pools similares en otros sitios se reconstruyen más rápido; este siempre se arrastra.

Causa raíz: Backplane/expander como cuello de botella, throttling térmico o cableado malo localizado en ese chasis.

Solución: Compara logs de errores entre hosts; intercambia cables; mueve un disco conocido bueno para reproducir; revisa temperaturas; valida compatibilidad de firmware del expander.

5) Los scrubs siempre encuentran “algunos errores”, pero a nadie le importa

Síntoma: Reparaciones de checksum regulares o errores permanentes ocasionales se normalizan.

Causa raíz: Decaimiento del medio subyacente o ruta I/O inestable; el scrub actúa como canario.

Solución: Trata las reparaciones de scrub como incidentes con umbrales; reemplaza discos sospechosos; valida cableado; asegura que el nivel de redundancia pueda tolerar la realidad.

6) Más tuning empeoró el resilver

Síntoma: Tras “tuning de rendimiento,” el resilver tarda más y la latencia sube.

Causa raíz: Tunings que aumentan la amplificación I/O o la carga de CPU; vdevs más anchos; recordsize equivocado; compresión/cifrado excesivo sin margen.

Solución: Revierte cambios; reevalúa con pruebas de la ruta de falla; diseña pensando en la reconstrucción, no solo en los dashboards.

Listas de verificación / plan paso a paso

Cuando un disco falla (RAIDZ): el runbook de incidente

  1. Congela la escena: captura zpool status -v, zpool events -v y dmesg -T para la línea temporal.
  2. Confirma redundancia restante: RAIDZ1 degradado = margen cero. RAIDZ2 degradado = un margen. Ajusta la urgencia en consecuencia.
  3. Revisa si hay un segundo disco débil: ejecuta SMART en todos los discos del vdev, al menos los sospechosos habituales (mismo modelo/lote, misma bahía, misma cadena de expander).
  4. Estabiliza la ruta: errores CRC o resets indican que arregles cableado/HBA antes de quemar más discos.
  5. Reemplaza el dispositivo fallado correctamente: usa zpool replace con IDs persistentes; evita la ruleta de nombres /dev/sdX.
  6. Reduce la carga competidora: pausa batch pesado, frena migraciones de VMs, difiere backups que golpeen el pool.
  7. Monitorea la tasa de resilver y errores: vigila crecimiento de CKSUM y ralentización que señalen la formación de una segunda falla.
  8. Tras el resilver, haz un scrub: valida el pool y saca corrupción latente mientras aún tienes redundancia.
  9. Haz una revisión post-incidente de capacidad y diseño: si el resilver tomó “demasiado,” es un problema de diseño, no mala suerte.

Checklist de diseño: construir RAIDZ para sobrevivir las matemáticas de reconstrucción

  1. Prefiere RAIDZ2 para vdevs HDD grandes: considera RAIDZ1 solo para archivo o discos pequeños donde las ventanas de exposición son cortas.
  2. Mantén la anchura del vdev razonable: vdevs más anchos aumentan el fan-out de lectura en reconstrucción y la concentración del riesgo.
  3. Mantén pools bajo un objetivo de utilización: planea 70–80% como “normal”, no como “desperdicio”.
  4. Programa scrubs con sentido: lo suficientemente frecuentes para detectar errores latentes antes de una falla; lo suficientemente espaciados para no ahogar producción.
  5. Estandariza nombres de dispositivo persistentes: usa rutas by-id, no /dev/sdX.
  6. Prueba comportamiento de resilver: en staging, simula reemplazo de disco y mide tiempos de reconstrucción con patrones de carga típicos.
  7. Mantén repuestos y personal disponible: tener un hot spare es bueno; tener alguien que conozca el procedimiento es mejor.

FAQ

1) ¿Es más seguro el resilver de RAIDZ que las reconstrucciones clásicas de RAID?

A menudo es más seguro porque ZFS tiene checksums de extremo a extremo y puede resilverizar bloques asignados, no cada LBA.
Pero RAIDZ1 degradado sigue siendo un filo de navaja: una falla adicional (disco, ruta o sector irreparable) puede acabar con el vdev.

2) ¿Por qué “scanned” excede a “issued” en zpool status?

“Scanned” es la cantidad que ZFS examinó; “issued” es IO realmente enviado para resilver. El escaneo puede incluir recorrido de metadatos y trabajo que no se traduce 1:1 en escrituras.
Si la tasa issued es baja, a menudo estás limitado por IO aleatorio, contención o un disco lento.

3) ¿Debería subir la prioridad de resilver para terminar más rápido?

A veces, pero solo con intención. Si ahogas demasiado el IO de producción, puedes provocar timeouts y fallas secundarias.
La acción más segura es reducir la carga primero (pausar batch, drenar VMs), luego ajustar si es necesario.

4) ¿RAIDZ2 garantiza que no perderé datos durante una reconstrucción?

No. Tolerará dos fallas de disco en un vdev, pero no te protege de: bugs de firmware, errores operativos, cables mal conectados, resets de controlador que afectan múltiples discos
o tres fallas concurrentes. Simplemente hace que un mal día común sea sobrevivible.

5) ¿Qué tan ancho debería ser un vdev RAIDZ2?

No hay un número mágico. Operacionalmente, “anchura razonable” significa: el tiempo de reconstrucción es aceptable y la latencia de un disco no domina.
Para pools de HDD, muchos equipos optan por vdevs RAIDZ2 de anchura moderada en lugar de monstruos ultra-anchos. Mide con tu carga.

6) ¿Por qué mi resilver se volvió más lento al 60% que al 10%?

Las fases tempranas pueden tocar regiones más secuenciales o metadatos cacheados. Fases posteriores pueden encontrar más asignaciones fragmentadas, datos más fríos y bloques más pequeños.
Además, otras cargas pueden volver a subir cuando la gente asume “ya casi terminó.”

7) Si SMART dice PASSED, ¿el disco está bien?

No. El estado global SMART es un resumen burdo. Observa sectores pendientes, offline uncorrectables y errores CRC.
Un disco puede “PASAR” mientras sabotea activamente tu resilver.

8) ¿Debería hacer scrubs más a menudo o menos?

Más seguido que “nunca”, menos seguido que “constantemente”. El objetivo es sacar a la luz errores latentes mientras aún tienes redundancia y antes de que una falla fuerce un resilver.
Si los scrubs afectan producción, prográmalos y controla la carga; no los abandones.

9) Mirrors vs RAIDZ por riesgo de reconstrucción—¿cuál es el trade-off?

Los mirrors resilverizan copiando de un disco superviviente a uno de reemplazo, típicamente más rápido y con menos fan-out de lectura.
RAIDZ tiene mejor eficiencia de capacidad pero mayor radio de impacto en la reconstrucción. Si tu carga es IOPS-intensa o tu RTO es estricto, los mirrors suelen ganar.

10) ¿Puedo simplemente “añadir un disco más” a un vdev RAIDZ para reducir riesgo?

El riesgo es principalmente sobre el nivel de paridad, tiempo de exposición de reconstrucción y comportamiento de errores. Añadir discos puede aumentar throughput, pero también ensanchar el dominio de falla.
Si necesitas más seguridad, aumenta paridad (RAIDZ2/3) o cambia la topología de vdev—no solo la anchura.

Próximos pasos que deberías tomar esta semana

Si ejecutas RAIDZ en producción, trata las matemáticas del resilver como un presupuesto. Estás gastando seguridad cada hora que estás degradado.
El trabajo es acortar la ventana e incrementar el margen.

  1. Audita el nivel de paridad: busca vdevs RAIDZ1 que sostengan datos importantes. Si los discos son HDD grandes, planea migración a RAIDZ2 o mirrors.
  2. Mide el tiempo real de resilver: no los MB/s del fabricante. Usa un ejercicio controlado de reemplazo en staging o en un pool no crítico y registra tiempos.
  3. Define cadencia y umbrales de scrub: decide qué número de reparaciones/errores de checksum dispara reemplazo de disco o inspección de cableado.
  4. Revisa ocupación y fragmentación del pool: si vives por encima de 80%, estás eligiendo reconstrucciones más largas y riesgosas.
  5. Endurece lo aburrido: nombres de dispositivo persistentes, discos de repuesto, firmware conocido-bueno y runbooks que no asuman heroísmos.

El día que pierdas datos rara vez es el día que falla el primer disco. Es el día que descubres que tus suposiciones sobre la reconstrucción eran fantasía.
Haz las matemáticas reales ahora, mientras aún puedes elegir la forma de tu falla.

← Anterior
Debian 13: registro de consultas lentas de MySQL — encuentra la consulta que te está matando en silencio
Siguiente →
Cortes por actualizaciones: cómo un parche malo puede tumbarlo todo

Deja un comentario