ZFS zpool status -v: Encontrar el archivo exacto que está corrupto

¿Te fue útil?

Cuando ZFS dice que encontró corrupción, lo hace con detalles—si formulas las preguntas correctas. El truco es que lo primero que verás rara vez será “/home/alice/report.xlsx está malo”, sino el estado del pool, un vdev y algunos contadores de checksum que parecen diseñados por alguien que odia dormir.

Este artículo trata de convertir zpool status -v de una luz roja aterradora en una lista accionable: qué está roto, dónde vive, si ZFS lo reparó y cómo extraer el/los archivo(s) afectados exactamente para poder restaurarlos o volver a copiarlos con confianza. Lo haremos como se hace en producción: diagnóstico rápido primero, forense profundo después y prevención siempre.

Qué significa realmente zpool status -v

A grandes rasgos, zpool status responde: “¿El pool está sano?” y “¿Qué dispositivo está implicado?” Añadir -v es la diferencia entre “algo está mal” y “estos archivos específicos son actualmente inválidos”.

Pero aquí va lo que la gente suele pasar por alto: zpool status -v no promete un nombre de archivo bonito cada vez. Imprime rutas solo para errores permanentes que ZFS puede asociar con archivos de datos y metadatos. Si ZFS reparó los datos durante un scrub (usando redundancia), el archivo puede nunca aparecer porque nunca estuvo dañado de forma permanente. Si el error está en metadatos que no pueden mapearse a una ruta de archivo (o no pueden decodificarse sin una inspección más profunda), verás números de objeto, o peor, solo “Permanent errors have been detected” sin una lista útil.

Piensa en los errores de ZFS en tres categorías:

  • Corregibles: Una lectura devolvió datos malos, pero ZFS tenía otra copia (mirror/RAIDZ) y la sanó.
  • No corregibles pero detectables: ZFS sabe que el checksum no coincide, pero no tiene una copia buena. Aquí es cuando empiezas a ver “permanent errors”.
  • Operacionales: timeouts, fallos de I/O, desconexiones. Estos pueden implicar o no corrupción de datos, pero a menudo conducen a ella si provocan escrituras parciales en dispositivos no atómicos o rutas inestables.

Dos chistes, como prometí, porque los vas a necesitar:

Chiste #1: ZFS no “pierde” datos: simplemente los guarda en una ubicación cuya existencia ya no puedes probar.

Chiste #2: Lo único más persistente que los checksums de ZFS es el VP preguntando si es “solo un reinicio”.

Leer las partes importantes de la salida de status

Aquí hay un punto de partida típico:

cr0x@server:~$ sudo zpool status -v tank
  pool: tank
 state: DEGRADED
status: One or more devices has experienced an unrecoverable error.  An
        attempt was made to correct the error.  Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
        using 'zpool clear' or replace the device with 'zpool replace'.
  scan: scrub repaired 0B in 02:14:33 with 0 errors on Tue Dec 24 03:10:11 2025
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        DEGRADED     0     0     0
          raidz1-0                  DEGRADED     0     0     0
            ata-WDC_WD80...-part1   ONLINE       0     0     0
            ata-WDC_WD80...-part1   ONLINE       0     0     2
            ata-WDC_WD80...-part1   ONLINE       0     0     0

errors: Permanent errors have been detected in the following files:

        tank/media/exports/2024-archive.tar
        tank/vmstore/vm-112-disk-0.qcow2

Lo que importa:

  • state: “DEGRADED” puede indicar que falta un disco o que existen errores. “ONLINE” no significa “bien”, significa “presente”.
  • READ/WRITE/CKSUM columnas: read/write son fallos de I/O; cksum es “datos devueltos pero equivocados”. Este último es donde a menudo aparece la corrupción silenciosa.
  • scan: resultados de scrub/resilver. “0 errors” en la línea del scrub no siempre significa “nunca pasó nada malo”, significa “el scrub no encontró problemas no corregidos en ese momento”.
  • errors: la lista “Permanent errors…” es oro. También puede estar incompleta cuando hay metadatos implicados.

Hechos y contexto histórico que realmente ayudan

Estos no son trivialidades por el gusto de ellas: cada uno influye en lo que haces a continuación.

  1. ZFS fue diseñado para desconfiar del almacenamiento. Los checksums son end-to-end: los datos se verifican después de salir del disco, no solo cuando se escriben.
  2. “Errores CKSUM” a menudo implican la ruta, no solo el disco: cables SATA, HBAs, backplanes, firmware de expander y la alimentación pueden voltear bits o perder comandos.
  3. Los scrubs son auditorías proactivas de integridad. Leen cada bloque y verifican checksums; los resilvers solo reconstruyen lo necesario después de un evento de dispositivo.
  4. ZFS mantiene múltiples capas de metadatos. Alguna corrupción afecta a un archivo; otra afecta metadatos que mapean bloques a archivos. Lo último puede ser más difícil de imprimir como una ruta.
  5. Los punteros de bloque incluyen checksums y ubicación física, que es cómo ZFS detecta datos erróneos incluso cuando el disco devuelve “éxito”.
  6. Las copias pueden existir sin mirrors: ZFS soporta múltiples copias de metadatos (y opcionalmente datos) mediante propiedades como copies=2. Esto cambia el comportamiento de reparación.
  7. “ashift” es para siempre (para ese vdev). Una alineación de tamaño de sector incorrecta puede aumentar la amplificación de escritura y estresar los dispositivos—a veces se convierte en la causa raíz en cámara lenta de corrupción posterior.
  8. La compresión cambia el radio de impacto. Los bloques comprimidos significan que los offsets lógicos de archivo no mapean 1:1 a bloques físicos, así que tu respuesta “¿qué parte está corrupta?” puede ser “un registro”, no “un sector”.
  9. ZFS puede sanar durante la lectura. En pools redundantes, leer un bloque corrupto puede desencadenar reparación incluso antes de que corra un scrub.

Guía rápida de diagnóstico

Este es el orden que uso cuando estoy de guardia y el pool acaba de volverse amarillo—o el equipo de aplicaciones está gritando porque una imagen de VM no arranca.

1) Confirmar el alcance: ¿a nivel de pool o un solo dataset/archivo?

cr0x@server:~$ sudo zpool status -v
  ...

Interpretación: Si ves “Permanent errors…” con rutas de archivos, ya tienes una lista objetivo. Si solo ves errores de dispositivo o “too many errors”, estás en el territorio de “estabilidad primero”: detén el sangrado antes de mapear forensemente.

2) Decidir si esto es corrupción o conectividad

cr0x@server:~$ sudo zpool status tank
  ...
        NAME                        STATE     READ WRITE CKSUM
        ata-WDC...                  ONLINE       0     0    54

Interpretación: Un aumento en CKSUM con READ/WRITE bajos a menudo significa que se están devolviendo datos malos (medio del disco, controlador, cable). Un aumento en READ/WRITE o dispositivos OFFLINE/FAULTED apunta más a reinicios de enlace, energía o un disco moribundo.

3) Comprobar si un scrub ya lo arregló

cr0x@server:~$ sudo zpool status -v tank
  scan: scrub repaired 0B in 02:14:33 with 0 errors on Tue Dec 24 03:10:11 2025

Interpretación: “Repaired X” significa que ZFS encontró bloques malos y los corrigió usando redundancia. Si reparó datos, vuelve a ejecutar la carga que falló y verifica si desapareció. Si todavía tienes “Permanent errors”, la redundancia no fue suficiente para esos bloques.

4) Identificar el dominio de falla: ¿un disco, un HBA, una línea de backplane?

cr0x@server:~$ ls -l /dev/disk/by-id/ | grep WDC_WD80 | head
  ...

Interpretación: Si los errores se agrupan en discos detrás del mismo controlador o expander, sospecha del componente compartido. Si es un solo disco repetidamente, sospecha de ese disco (o su ranura/cable).

5) Si el pool es inestable, estabilízalo antes del mapeo profundo

Si los dispositivos están cayendo, no ejecutes arqueología zdb primero. Arregla el cableado, reemplaza el disco, detén los reinicios. Un scrub en un disco intermitente puede convertir lo “recuperable” en “permanente” al fallar lecturas repetidamente.

Tareas prácticas: comandos + interpretación (12+)

Estas son tareas que he ejecutado bajo presión. Cada una incluye qué significa la salida y qué decisión debe guiar.

Tarea 1: Obtener la vista de alto nivel del pool

cr0x@server:~$ sudo zpool status -xv
all pools are healthy

Interpretación: -x imprime solo pools con problemas; -v añade listas de archivos si están disponibles. Si obtienes “healthy”, deja de cavar. Si no, continúa.

Tarea 2: Sacar el estado verbose de un pool específico

cr0x@server:~$ sudo zpool status -v tank
  pool: tank
 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
...
errors: Permanent errors have been detected in the following files:

        tank/projects/build-cache/index.sqlite

Interpretación: Incluso “ONLINE” puede significar que ocurrió corrupción de datos. Si las aplicaciones “may be affected”, trátalo como “están afectadas hasta demostrar lo contrario”.

Tarea 3: Encontrar cuándo comenzaron los errores (historial de eventos)

cr0x@server:~$ sudo zpool events -v | tail -n 30
  ...

Interpretación: Busca eventos de remoción de dispositivo, errores de checksum o inicio/fin de resilver. Esto a menudo se correlaciona con ventanas de mantenimiento, actualizaciones del kernel o alguien “ordenando cables”.

Tarea 4: Ejecutar (o re-ejecutar) un scrub intencionalmente

cr0x@server:~$ sudo zpool scrub tank

Interpretación: El scrub es el suero de la verdad de integridad. Ejecútalo cuando el pool esté estable. Si estás en medio de un incidente, scrubbing inmediatamente puede ser correcto—a menos que sospeches inestabilidad de hardware, en cuyo caso arregla eso primero.

Tarea 5: Vigilar el progreso del scrub sin adivinar

cr0x@server:~$ watch -n 5 "sudo zpool status tank | sed -n '1,25p'"
Every 5.0s: sudo zpool status tank | sed -n '1,25p'

  pool: tank
 state: ONLINE
  scan: scrub in progress since Wed Dec 25 01:10:11 2025
        612G scanned at 1.20G/s, 110G issued at 220M/s, 4.21T total
        0B repaired, 2.61% done, 0:52:01 to go

Interpretación: “scanned” vs “issued” te dice si el scrub está limitado por I/O. Si issued es bajo, podrías estar limitado por latencia de vdev, comportamiento SMR o throttling.

Tarea 6: Borrar errores (solo después de entender lo que borras)

cr0x@server:~$ sudo zpool clear tank

Interpretación: Esto borra contadores y el estado “known bad”; no arregla datos mágicamente. Úsalo después de reemplazar hardware o tras restaurar/reemplazar archivos corruptos para poder ver si los errores regresan.

Tarea 7: Identificar si “CKSUM” sigue subiendo

cr0x@server:~$ sudo zpool status tank | awk 'NR==1,NR==40 {print}'
  ...

Interpretación: Toma dos instantáneas en el tiempo. Si CKSUM incrementa mientras está inactivo, sospecha firmware/hardware. Si incrementa solo durante lecturas intensas, sospecha medio marginal o errores del controlador bajo carga.

Tarea 8: Comprobar salud del dispositivo (SMART) para el sospechoso

cr0x@server:~$ sudo smartctl -a /dev/sdc | egrep -i "realloc|pending|uncorrect|crc|error|self-test"
  199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       23
  197 Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       0

Interpretación: Los errores UDMA CRC gritan “cable/backplane/controlador”, no “medio del disco”. Sectores reasignados/pendientes sugieren que el disco en sí está fallando. Ninguno es un oráculo perfecto; úsalo para elegir qué reemplazar primero.

Tarea 9: Revisar logs del kernel por reinicios y errores de I/O

cr0x@server:~$ sudo dmesg -T | egrep -i "zfs|sd.*error|ata.*error|reset|I/O error|checksum" | tail -n 40
  ...

Interpretación: Si ves reinicios de enlace, timeouts de comandos o resets de bus alrededor del momento en que ZFS detectó corrupción, el “archivo corrupto” es el síntoma, no la enfermedad.

Tarea 10: Obtener mountpoints de datasets y confirmar que la ruta es real

cr0x@server:~$ zfs list -o name,mountpoint,compression,recordsize -r tank | head -n 20
NAME                     MOUNTPOINT              COMPRESS  RECORDSIZE
tank                     /tank                   lz4       128K
tank/media               /tank/media             lz4       1M
tank/vmstore             /tank/vmstore           lz4       128K

Interpretación: Si zpool status -v lista tank/vmstore/..., necesitas saber dónde está en disco (/tank/vmstore) y qué implicaciones tienen recordsize/compression para la recuperación a nivel de aplicación.

Tarea 11: Verificar que el archivo se puede leer end-to-end (y desencadenar curación si es redundante)

cr0x@server:~$ sudo dd if=/tank/media/exports/2024-archive.tar of=/dev/null bs=4M status=progress
  2147483648 bytes (2.1 GB, 2.0 GiB) copied, 4 s, 536 MB/s
  ...

Interpretación: Si la lectura falla o se queda estancada, has confirmado el impacto. En pools redundantes, una lectura también puede provocar que ZFS repare; tras una lectura exitosa, comprueba si los contadores CKSUM cambiaron.

Tarea 12: Si tienes snapshots, restaurar solo el archivo

cr0x@server:~$ zfs list -t snapshot -o name,creation -S creation | head
NAME                          CREATION
tank/media@autosnap_2025-12-24_0300  Tue Dec 24 03:00 2025
tank/media@autosnap_2025-12-23_0300  Mon Dec 23 03:00 2025

cr0x@server:~$ sudo cp -a /tank/media/.zfs/snapshot/autosnap_2025-12-24_0300/exports/2024-archive.tar /tank/media/exports/2024-archive.tar

Interpretación: A menudo esta es la reparación más rápida: reemplazar el archivo corrupto por una versión conocida buena. Si es un disco de VM, puede ser preferible restaurarlo con un nombre nuevo y hacer comprobaciones de integridad antes de intercambiar.

Tarea 13: Si no hay snapshots, verificar un réplica o volver a copiar desde origen

cr0x@server:~$ sudo rsync -avh --inplace --checksum /mnt/source/2024-archive.tar /tank/media/exports/2024-archive.tar
sending incremental file list
2024-archive.tar
          4.21T 100%  1.05GB/s    1:04:10 (xfr#1, to-chk=0/1)

Interpretación: --checksum fuerza verificación más allá de las marcas de tiempo; --inplace es controvertido en sistemas copy-on-write, pero puede ser apropiado cuando quieres reescribir bloques sin crear una segunda copia completa. Úsalo con cuidado (ver sección de errores).

Tarea 14: Reemplazar un disco que falla de forma limpia

cr0x@server:~$ sudo zpool replace tank ata-WDC_WD80...-old /dev/disk/by-id/ata-WDC_WD80...-new
cr0x@server:~$ sudo zpool status tank
  scan: resilver in progress since Wed Dec 25 02:11:12 2025
        310G scanned at 1.05G/s, 92.1G issued at 320M/s, 4.21T total
        0B resilvered, 2.19% done, 3:40:21 to go

Interpretación: El reemplazo aborda el riesgo subyacente. No arregla automáticamente bloques ya corruptos a menos que existiera redundancia y el pool pueda reconstruirlos durante lecturas de scrub/resilver.

Tarea 15: Usar checksums a nivel ZFS para verificar un dataset (sanity rápida)

cr0x@server:~$ sudo zfs set readonly=on tank/media
cr0x@server:~$ sudo zpool scrub tank
cr0x@server:~$ sudo zfs set readonly=off tank/media

Interpretación: Poner temporalmente un dataset como solo lectura reduce la agitación por escrituras durante la investigación y puede evitar que una aplicación sobrescriba evidencia. No lo hagas en datasets de aplicaciones en vivo sin coordinación.

Mapear errores del pool a archivos exactos (el flujo real)

Si zpool status -v ya imprime rutas de archivos, felicidades—vas por delante del caso habitual. Aún necesitas responder tres preguntas:

  1. ¿El archivo está realmente corrupto ahora, o fue reparado?
  2. ¿La corrupción se limita a ese archivo, o es señal de un problema más profundo?
  3. ¿Cuál es la acción de recuperación más rápida y segura?

Cuando zpool status -v te da rutas de archivos

ZFS listará rutas que puede asociar con errores permanentes. Para cada ruta listada:

  1. Intenta leerla end-to-end (o al menos la porción crítica).
  2. Si es redundante, verifica si la lectura desencadena reparación (observa CKSUM y scrubs posteriores).
  3. Restaura desde snapshot o vuelve a copiar desde la fuente.
  4. Borra errores y scrubea de nuevo para confirmar que el pool está limpio.

Bucle de verificación de ejemplo:

cr0x@server:~$ sudo zpool status -v tank
errors: Permanent errors have been detected in the following files:
        tank/projects/build-cache/index.sqlite

cr0x@server:~$ sudo sqlite3 /tank/projects/build-cache/index.sqlite "PRAGMA integrity_check;"
*** in database main ***
On tree page 914 cell 27: Rowid 188394 out of order
database disk image is malformed

Interpretación: La base de datos está realmente dañada a nivel de aplicación. ZFS hizo su trabajo al decirte “este archivo no es confiable”. Tu trabajo es restaurar/reconstruir la base de datos, no discutir con ella.

Cuando zpool status -v NO te da rutas de archivos

Este es el caso más interesante. Podrías ver:

  • “Permanent errors have been detected…” pero sin lista
  • “too many errors”
  • errores atribuidos a metadatos (a veces mostrados como <metadata> o IDs de objeto según la plataforma)

Cuando ZFS no puede imprimir una ruta, aún puedes mapear corrupción a archivos usando números de objeto y zdb. La idea es:

  1. Identificar el dataset que contiene los bloques malos (a menudo sugerido en status o por el impacto en la carga).
  2. Usar zdb para inspeccionar objetos del dataset y localizar el/los número(s) de objeto afectados.
  3. Mapear números de objeto a rutas (cuando sea posible) o al menos identificar el tipo de archivo (zvol, dnode, directorio, etc.).

Advertencia operativa importante: zdb es potente y afilado. Usa flags de solo lectura donde estén disponibles, ejecútalo en horas de baja carga si es posible y captura la salida para revisión posterior. No debería modificar el pool, pero en una crisis no quieres sorpresas.

Tarea: Identificar datasets y si la corrupción probablemente afecta a un zvol

cr0x@server:~$ zfs list -t filesystem,volume -o name,type,used,volsize -r tank
NAME                 TYPE        USED  VOLSIZE
tank                 filesystem  3.21T  -
tank/media           filesystem  1.88T  -
tank/vmstore         filesystem  1.02T  -
tank/vmstore/vm-112  volume      120G  120G

Interpretación: Si lo afectado es un volume (zvol), no aparecerá como una ruta de archivo regular de la misma manera. Tu “archivo” puede ser un dispositivo de bloque consumido por un hipervisor o un target iSCSI.

Tarea: Comprobar si la ruta reportada está dentro de un snapshot, clone o filesystem actual

cr0x@server:~$ sudo zpool status -v tank | sed -n '/Permanent errors/,$p'
errors: Permanent errors have been detected in the following files:
        tank/media/exports/2024-archive.tar

cr0x@server:~$ ls -lah /tank/media/exports/2024-archive.tar
-rw-r--r-- 1 root root 4.3T Dec 21 01:01 /tank/media/exports/2024-archive.tar

Interpretación: Valida que el archivo exista donde piensas que está. Suena obvio; en el mundo real, los puntos de montaje cambian, ocurren bind mounts y alguien insistirá en que “está bajo /srv”.

Tarea: Usar zdb para mapear una ruta a información interna de objetos (avanzado)

En muchos sistemas OpenZFS puedes preguntar a zdb sobre una ruta de archivo dentro de un dataset. Un patrón común es: encontrar el dataset, luego consultar con zdb para localizar el dnode/objeto.

cr0x@server:~$ sudo zdb -ddd tank/media | head -n 25
Dataset tank/media [ZPL], ID 52, cr_txg 1, 1.88T, 9.21M objects

    Object  lvl   iblk   dblk  dsize  dnsize  lsize   %full  type
         1    1   128K    1K  16.0K     512  1.50K  100.00  ZFS master node
         2    1   128K    1K  16.0K     512  14.5K  100.00  ZFS directory
  ...

Interpretación: Esto confirma el tipo de dataset (ZPL filesystem) y que zdb puede leer metadatos. Si zdb arroja errores de I/O, detente y estabiliza el hardware.

Tarea: Identificar el inode/objeto de un archivo (enfoque portátil)

cr0x@server:~$ stat -c 'path=%n inode=%i size=%s' /tank/media/exports/2024-archive.tar
path=/tank/media/exports/2024-archive.tar inode=188394 size=4639123456789

Interpretación: En ZFS, el número de inode a menudo corresponde a un número interno de objeto (dnode) para filesystems ZPL. Eso puede ser el puente entre “ruta de archivo” y “objeto 188394” que puedas ver en otros lugares.

Tarea: Profundizar en un objeto específico con zdb (mapeo forense)

cr0x@server:~$ sudo zdb -dddd tank/media 188394 | sed -n '1,120p'
Object  lvl   iblk   dblk  dsize  dnsize  lsize   %full  type
188394    2   128K  128K  1.00M    512  4.21T   98.11  ZFS file
Bonus System attributes
  ZPL_SIZE 4639123456789
  ZPL_GEN  4821
Indirect blocks:
  ...

Interpretación: Si puedes inspeccionar el objeto limpiamente, a veces puedes profundizar y localizar qué puntero(s) de bloque están fallando, lo que ayuda a diferenciar “un sector malo” de “problema extendido”. Más importante: confirma que estás mirando lo correcto.

Tarea: Probar si la corrupción está localizada o es sistémica

cr0x@server:~$ sudo zpool status tank | egrep -A3 "NAME|raidz|mirror|ata-|nvme"
        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          raidz1-0                  ONLINE       0     0     0
            ata-WDC...-part1        ONLINE       0     0     0
            ata-WDC...-part1        ONLINE       0     0     2
            ata-WDC...-part1        ONLINE       0     0     0

Interpretación: “2 CKSUM en un disco” podría ser un evento aislado de bit rot o un estornudo de cable. “Miles en múltiples discos” suele ser infraestructura: HBA, backplane, firmware, energía o un lote malo de unidades.

Tarea: Si los errores están en un solo vdev de alto nivel, entender el radio de impacto

cr0x@server:~$ sudo zpool list -v tank
NAME         SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH
tank        21.8T  16.2T  5.6T        -         -    22%    74%  1.00x  ONLINE
  raidz1-0  21.8T  16.2T  5.6T        -         -    22%    74%

Interpretación: Los pools de vdev único son comunes. Si ese vdev tiene problemas, la integridad de todo el pool depende de él. Pools con múltiples vdevs pueden tener aislamiento de fallos, pero también complejidad operativa mayor.

Tarea: Comprobar si vdevs especiales o dispositivos de metadatos están involucrados

cr0x@server:~$ sudo zpool status tank | sed -n '1,120p'
  pool: tank
 state: ONLINE
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          raidz2-0                  ONLINE       0     0     0
            ...
        special
          mirror-1                  ONLINE       0     0     0
            nvme-SAMSUNG...         ONLINE       0     0     0
            nvme-SAMSUNG...         ONLINE       0     0     0

Interpretación: Si un vdev special está fallando (metadatos/bloques pequeños), puedes ver síntomas de “corrupción de archivos” que parecen aleatorios y aterradores. Trata la fiabilidad del vdev special como crítica. Si falla y no tienes redundancia, el pool puede estar efectivamente perdido incluso si los discos de datos están bien.

Tarea: Si sospechas “RAM mala” o corrupción transitoria de memoria

cr0x@server:~$ sudo zpool status -v tank
  status: One or more devices has experienced an error resulting in data corruption.
  ...

Interpretación: ZFS no es inmune a la RAM defectuosa. ECC ayuda. Sin ECC, puedes seguir usando ZFS, pero deberías ser más paranoico: errores de checksum repetibles en distintos discos sin una ruta de hardware clara pueden ser una pista. Correlaciona con logs del sistema, caídas y otras anomalías.

Tres mini-historias del mundo corporativo

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

Una empresa con la que trabajé tenía una regla “simple”: si zpool status dice ONLINE, el almacenamiento está bien. Esa regla vivía en un runbook, lo que significó que eventualmente pasó de “atajo útil” a “política”.

Una mañana, una imagen de VM no arrancaba. Los logs del hipervisor mostraban errores de I/O; el nodo de almacenamiento mostraba el pool ONLINE. Así que el responsable declaró la capa de almacenamiento “limpia” y empujó al equipo de virtualización a “arreglar el guest”. Clásico juego de pasar la papa caliente, pero con más canales de Slack.

Alguien finalmente ejecutó zpool status -v (no solo zpool status) y obtuvo un error permanente listando el exacto archivo .qcow2 de respaldo. El pool estaba ONLINE porque los vdevs estaban presentes; los datos no estaban bien porque el pool tenía fallos de checksum no corregibles en algunos bloques.

La suposición equivocada no fue “ZFS miente”. Fue “ONLINE significa sano”. ONLINE significa “el pool es accesible”. No garantiza que cada byte esté intacto. Después de ese incidente, el equipo cambió la regla: el almacenamiento es “verde” solo si zpool status -xv está limpio y el último scrub se completó sin errores no corregidos.

La reparación fue aburrida: restaurar el disco de la VM desde el snapshot de la noche anterior, luego scrubea el pool y reemplazar el hardware de la ruta de disco sospechosa. La lección caló porque fue costosa: la VM había sido “reparada” reinstalando paquetes por dos horas antes de que alguien probara que la imagen del disco estaba corrupta.

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

Otro lugar decidió que los scrubs eran “demasiado costosos” durante horario laboral. Tenían cargas analíticas y no querían que el ancho de banda de lectura fuese consumido por escaneos de integridad. Así que movieron los scrubs a una programación mensual y los throttlearon agresivamente.

En papel, parecía responsable: menos scrubs, menos I/O, dashboards más felices. En la práctica, amplió la ventana de detección. Un solo cable SAS marginal empezó a producir errores intermitentes de checksum. Nada se cayó. El pool siguió sanando lo que pudo. Y como los scrubs eran raros, el problema permaneció invisibile el tiempo suficiente para que un segundo disco desarrollara errores reales de medio.

Cuando finalmente corrió el scrub mensual, encontró bloques no corregibles esparcidos por varios datasets. zpool status -v listó un puñado de archivos, pero el daño a metadatos hizo que algunos errores no se mapearan limpiamente a rutas. La recuperación se convirtió en una mezcla desordenada de restaurar snapshots, verificar bases de datos y explicar a la dirección por qué “tenemos RAIDZ, así que estamos seguros” no es una frase que quieras en un postmortem.

La optimización no fue solo el calendario: fue la confianza que creó. Trataron el scrubbing como opcional. Los scrubs están más cerca de “pruebas de alarma de incendio”. Son disruptivos hasta el día que los necesitas, y entonces desearás haberlos ejecutado con regularidad.

El resultado: volvieron a scrubs semanales, ajustaron la velocidad del scrub según SLOs de latencia y empezaron a alertar sobre cualquier delta CKSUM no nulo por día. Lo curioso es que el cluster funcionó más rápido después, porque se arreglaron los errores de enlace subyacentes y las reintentos dejaron de arrastrar la latencia.

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

El incidente de corrupción más exitoso que vi fue casi anticlimático. Un nodo de almacenamiento reportó algunos errores CKSUM y zpool status -v listó dos archivos: un archivo exportado y un pequeño segmento WAL de Postgres.

El equipo tenía un hábito—algunos lo llamaban paranoico—de tomar snapshots frecuentes y replicar datasets críticos. No era nada sofisticado: nombres consistentes, políticas de retención, pruebas periódicas de restauración. El tipo de cosas que nadie celebra porque no entrega features.

Hicieron lo básico: pausaron el job que ingería datos al dataset, restauraron los dos archivos desde un snapshot tomado una hora antes y ejecutaron un scrub para validar que no existieran otros errores no corregidos. También revisaron SMART y notaron errores UDMA CRC en un disco, cambiaron el cable durante la ventana de mantenimiento y vieron cómo el contador CKSUM dejó de moverse.

No hubo exploración heroica con zdb. No “quizá el filesystem se arregle solo”. Solo higiene disciplinada. La revisión post-incident duró 20 minutos porque no quedaba mucho drama que narrar, que es el mejor tipo de revisión.

Si quieres una moraleja: los snapshots no previenen la corrupción, pero la convierten en una molestia. Y en la vida corporativa, una molestia es básicamente una victoria.

Errores comunes: síntomas y soluciones

Mistake 1: Borrar errores antes de restaurar archivos

Síntoma: Ejecutas zpool clear, el status parece limpio, luego la aplicación lee el archivo y vuelve a fallar más tarde—o pierdes la pista de qué archivos estaban afectados.

Solución: Trata la lista “Permanent errors” como un artefacto del incidente. Cópiala al ticket, restaura/reemplaza los archivos y luego borra y scrubea para confirmar. Borrar es para verificar recurrencia, no para negar el problema.

Mistake 2: Suponer que CKSUM significa “el disco está malo” (puede ser, pero no siempre)

Síntoma: Reemplazas un disco, la resilver termina y los errores CKSUM siguen subiendo—a veces en el disco de reemplazo.

Solución: Revisa el cableado SATA/SAS, backplanes, HBAs, firmware de expander y estabilidad de la energía. Observa SMART UDMA CRC y logs del kernel por reinicios de enlace.

Mistake 3: Scrub en hardware inestable

Síntoma: Un disco está cayendo intermitentemente; haces un scrub; al final tienes más errores permanentes que antes.

Solución: Estabiliza primero. Scrub es una lectura de superficie completa. Si la ruta es inestable, estás forzando al sistema a tocar el punto débil repetidamente. Reemplaza el cable/HBA/disco según corresponda, luego scrubea.

Mistake 4: Confundir “repaired 0B” con “nunca hubo corrupción”

Síntoma: El scrub informa “0B repaired”, pero aún ves errores permanentes o corrupción a nivel de aplicación.

Solución: “0B repaired” puede significar “nada estaba mal” o “nada pudo repararse”. Revisa siempre la sección “errors:” y los contadores de errores del dispositivo.

Mistake 5: Ignorar implicaciones de metadatos/vdev special

Síntoma: Archivos aleatorios en distintos datasets fallan; la salida de zpool status -v es escasa o extraña; el rendimiento se vuelve errático.

Solución: Comprueba si existen vdevs special y si están sanos. Trátalos como críticos. Si un vdev special falla y no tienes redundancia, el pool puede estar efectivamente perdido aun cuando los discos de datos parezcan bien.

Mistake 6: Tratar un archivo de disco VM como un archivo normal durante la recuperación

Síntoma: Restauras un .qcow2 o imagen raw “in place” mientras la VM está en ejecución; luego obtienes corrupción sutil en el filesystem del guest.

Solución: Quiesce la VM, restaura a un archivo nuevo, realiza comprobaciones a nivel de guest si es posible y luego intercambia. Las imágenes de VM son grandes, calientes y sensibles a flujos de restauración parciales.

Mistake 7: Activar una “optimización” sin entender los patrones de escritura

Síntoma: Tras cambiar recordsize, compression o usar rsync --inplace, ves más fragmentación, scrubs más largos o picos de latencia inesperados.

Solución: Trata el tuning de rendimiento como una solicitud de cambio: mide, haz staging y revierte si sale mal. Los flujos de integridad dependen de un comportamiento de I/O predecible.

Listas de verificación / plan paso a paso

Checklist A: Plan de respuesta “acabo de ver corrupción”

  1. Captura evidencia: zpool status -v, zpool events -v, extractos de dmesg.
  2. Determina si el pool es estable (dispositivos no están flapeando). Si es inestable, prioriza estabilización de hardware.
  3. Si zpool status -v lista archivos, inventaría y clasifícalos: DB/VM críticas primero.
  4. Ejecuta o programa un scrub (cuando esté estable). Monitorea progreso y errores.
  5. Restaura/reemplaza archivos corruptos desde snapshots o fuente upstream.
  6. Borra errores (zpool clear) solo después de la remediación.
  7. Rescrubea para validar y observa contadores por regresión.
  8. Investiga la causa raíz en hardware: SMART, cableado, firmware del controlador, eventos de energía.

Checklist B: Paso a paso para encontrar “el archivo exacto”

  1. Ejecuta zpool status -v. Si obtienes rutas de archivos, detente aquí—ya las tienes.
  2. Si no hay rutas, identifica vdev/disco afectado vía contadores de error.
  3. Identifica dataset probable por impacto en carga (qué mountpoint/app ve errores) y revisando historial de eventos.
  4. Usa stat en archivos sospechosos para obtener inode/números de objeto.
  5. Usa zdb para inspeccionar dataset y detalles de objetos; confirma tipos de objeto.
  6. Una vez tengas un archivo/objeto sospechoso, intenta lecturas controladas para confirmar.
  7. Recupera desde snapshot/replica; valida integridad a nivel de aplicación (chequeos de DB, pruebas de archivos, arranque de VM).

Checklist C: Verificación post-arreglo

  1. zpool status -xv debe estar limpio.
  2. El scrub se completa con 0 errors.
  3. Los contadores CKSUM dejan de aumentar tras reanudar cargas normales.
  4. SMART y logs del kernel no muestran reinicios de enlace/timeouts.
  5. Pruebas de restauración demuestran que backups/snapshots son válidos.

FAQ

1) ¿zpool status -v siempre muestra el nombre exacto del archivo?

No. Muestra rutas de archivo cuando ZFS puede mapear errores permanentes a un archivo en un filesystem ZPL. Si la corrupción está en metadatos, afecta objetos no mapeables, involucra un zvol o ZFS no puede resolver la ruta de forma segura, puede no aparecer ningún nombre o solo referencias tipo objeto.

2) ¿Cuál es la diferencia entre errores READ, WRITE y CKSUM?

READ/WRITE son fallos de I/O (el dispositivo no pudo leer/escribir exitosamente). CKSUM significa que el dispositivo devolvió datos con éxito, pero no coincidieron con el checksum esperado—a menudo apunta a corrupción silenciosa o a una ruta mala (cable/HBA/backplane).

3) Si ZFS reparó datos durante un scrub, ¿tengo que hacer algo?

Sí: necesitas encontrar la causa raíz. Una reparación significa que la redundancia te salvó esta vez. Revisa contadores de dispositivo, SMART y logs. Un evento reparado puede ser un rayo cósmico; reparaciones repetidas son un problema de hardware postulándose para un rol permanente.

4) ¿Debo ejecutar un scrub inmediatamente tras ver errores?

Si la ruta de hardware está estable, sí—el scrub te da la verdad y puede reparar. Si los dispositivos están flapeando o ves resets/timeouts, arregla la estabilidad primero; hacer scrub en hardware inestable puede aumentar lecturas no corregibles.

5) ¿Cuál es la forma más rápida de “arreglar” un archivo listado como corrupto?

Restáuralo desde un snapshot (/path/.zfs/snapshot/...) o vuelve a copiarlo desde una fuente conocida buena. Luego borra errores y scrubea de nuevo para validar. Para bases de datos e imágenes de VM, realiza también comprobaciones de integridad a nivel de aplicación.

6) ¿Un cable SATA/SAS malo puede realmente causar errores de checksum?

Absolutamente. Es una de las causas más comunes que la gente descarta. El contador UDMA CRC de SMART y los logs del kernel sobre reinicios de enlace son señales fuertes. Cambia el cable, vuelve a asentar conectores y asegúrate de que el backplane esté sano.

7) Si reemplazo el disco, ¿el archivo corrupto se arreglará automáticamente?

Solo si la redundancia permite reconstruir el bloque malo y el pool realmente lo lee y repara (scrub/heal-on-read). Si el pool nunca tuvo una copia buena (o la corrupción existía en todas las copias), reemplazar hardware no resucitará los datos—aún necesitarás snapshots/backups.

8) ¿Por qué zpool status a veces dice “applications are unaffected” cuando lista errores?

Esa línea suele aparecer cuando ZFS detectó y corrigió un problema (o cree haberlo hecho). Trátalo como “no se observaron fallos I/O inmediatos por parte de las aplicaciones”, no como una garantía. Si hay errores permanentes, algunos datos no son confiables.

9) ¿Qué significa “too many errors”?

ZFS te está diciendo que la tasa de errores es lo bastante alta como para que listar todo sea impráctico, o la situación está empeorando activamente. Concéntrate en estabilizar hardware, ejecutar un scrub y priorizar datasets afectados según síntomas de aplicación.

10) ¿Puedo usar zpool clear para quitar el mensaje aterrador?

Puedes, pero es como quitar la batería del detector de humo porque suena. Borra solo después de la remediación para poder detectar si los errores regresan. Si borras primero, pierdes una pista clave.

Conclusión

zpool status -v es una de las raras herramientas en infraestructura que es honesta y útil: te dice lo que ZFS puede probar, no lo que quieres oír. Cuando imprime una lista de archivos, trata esa salida como una lista quirúrgica: verifica, restaura, valida, luego borra y rescrubea. Cuando no imprime rutas, no te asustes; suele significar que la corrupción está en metadatos o es difícil de mapear, y eso es tu señal para estabilizar hardware y escalar a una inspección más profunda con zdb y razonamiento a nivel de objetos.

La victoria operativa no es solo encontrar el archivo corrupto. Es crear un hábito: scrubs frecuentes que encajen en tu presupuesto de latencia, snapshots que realmente has probado y alertas que capturan un contador CKSUM en ascenso antes de que se convierta en titular del postmortem.

← Anterior
Redes en Proxmox vs ESXi: trunk VLAN, bridges/vSwitches, bonding/LACP explicado
Siguiente →
MySQL vs ClickHouse para paneles en tiempo real: construir rápido sin tumbar el checkout

Deja un comentario