La mayoría de los incidentes son ruidosos: un controlador muere, se cae un enlace, un disco sale del pool como un actor problemático que abandona una reunión temprano. La corrupción silenciosa es lo opuesto. Tus aplicaciones siguen devolviendo HTTP 200 mientras tus datos se pudren en silencio. Luego, un día restauras una copia, ejecutas un informe, abres una foto, reproduces un vídeo o arrancas una base de datos, y descubres qué se siente un “checksum mismatch” en el estómago.
ZFS es uno de los pocos sistemas de archivos mainstream que trata “mi almacenamiento dijo que escribió los datos” como una hipótesis a probar, no como una promesa. Los scrub son cómo lo pruebas a escala. Bien hechos, son aburridos, regulares y salvan vidas. Mal hechos, son teatro —o se convierten en la razón por la que tu gráfico de latencia de producción parece un sismógrafo.
Corrupción silenciosa: qué es (y por qué no te darás cuenta)
La corrupción silenciosa de datos ocurre cuando los bits cambian sin que tu software sea notificado. No hay error de E/S. No hay kernel panic. No hay controlador RAID gritando. La lectura tiene éxito y devuelve bytes—simplemente no son los bytes que escribiste. Eso es lo que la convierte en un problema de fiabilidad, no solo de hardware.
Hay varias formas comunes en que ocurre:
- Errores de medio que no se manifiestan como errores. Los discos pueden devolver lecturas “exitosas” con datos incorrectos debido a fallos internos, errores de firmware, sectores marginales o algoritmos de recuperación que adivinan mal.
- Escrituras defectuosas. Pérdida de energía, errores en el caché de escritura o cables/controladores inestables pueden hacer que una escritura quede parcial o incorrecta.
- Corrupción de memoria. Los datos estaban bien en disco, pero la RAM cambió un bit antes de que se calculase el checksum o antes de que se escribieran.
- Problemas DMA/cableado. Un HBA, backplane o cable ligeramente defectuoso puede corromper datos en tránsito. El disco hizo exactamente lo que se le indicó. El problema es que tú le dijiste la cosa equivocada.
Los sistemas de archivos clásicos generalmente tienen dos opciones: confiar en la pila debajo de ellos, o añadir checksums parciales solo para metadatos. ZFS no confía. Verifica.
Un consuelo seco: la corrupción silenciosa es rara en sistemas bien construidos. Una advertencia seca: “rara” no es una estrategia. Tampoco lo es “tenemos RAID”.
Broma #1: RAID significa “Redundant Array of Inexplicable Decisions” cuando asumes que verifica tus datos. Normalmente no lo hace.
Cómo ZFS detecta la corrupción: checksums, auto-reparación y los límites
ZFS verifica los datos end-to-end almacenando un checksum para cada bloque (datos y metadatos) y validándolo cuando se lee el bloque. Esto importa porque el checksum se guarda separado de los datos que protege—típicamente en el puntero del bloque padre—por lo que un único sector dañado no puede convenientemente dañar a la vez los datos y su checksum.
Qué significa “end-to-end” en la práctica
Cuando una aplicación escribe un bloque:
- ZFS calcula un checksum del contenido del bloque.
- ZFS escribe el nuevo bloque en disco (copy-on-write), luego actualiza la metadata para apuntar a él, incluyendo el checksum.
- Más tarde, cuando se lee el bloque, ZFS recomputa el checksum y lo compara con el almacenado.
Si el checksum no coincide, ZFS sabe que los datos están mal. Eso ya es importante: detectar supera al fallo silencioso. Pero ZFS también puede repararlo si le diste redundancia.
Auto-reparación: solo si tienes una copia buena
Con mirrors o RAIDZ, ZFS puede leer de otra réplica/conjunto de paridad, encontrar una versión correcta y reescribir la copia dañada. Esa es la “auto-reparación” de la que escuchas. Sin redundancia (un pool de disco único), ZFS aún detecta corrupción, pero no puede conjurar datos correctos desde el vacío.
Este es el modelo mental no negociable:
- Los checksums detectan la corrupción.
- La redundancia repara la corrupción.
- Los scrub fuerzan la verificación a escala.
Qué no son los scrub
Un scrub no es un botón mágico de “arregla mi pool”. Es una lectura y verificación sistemática de los datos y metadatos del pool, reparando lo que puede usando redundancia. No hará:
- Arreglar corrupción que existe idénticamente en todas las réplicas (datos malos escritos de forma consistente).
- Arreglar corrupción a nivel de aplicación (la app escribió basura; ZFS la preservó fielmente).
- Reemplazar backups o versionado. Si la corrupción es antigua y la descubres tarde, puede que necesites copias históricas.
Y un scrub no es lo mismo que un resilver. Resilver es la reconstrucción dirigida tras reemplazar o volver a conectar un dispositivo. Scrub es la verificación periódica de todo.
Una idea parafraseada que ha envejecido bien: paraphrased idea
de John Allspaw (operaciones/fiabilidad): “Los sistemas fallan de maneras desordenadas y sorprendentes; necesitas bucles de retroalimentación que te digan cuando la realidad diverge de las suposiciones.” Los scrub son uno de esos bucles de retroalimentación.
Qué hace realmente un scrub
Un scrub de ZFS recorre el árbol de bloques del pool y emite lecturas para cada bloque asignado. Para cada bloque, verifica el checksum. Si el checksum falla y existe redundancia, ZFS lee copias alternas/paridad, repara la copia mala y registra el evento. Si no hay redundancia o el daño es irrecuperable, verás errores permanentes.
Perfil de la carga de trabajo del scrub
Los scrub son mayormente lecturas secuenciales a nivel de vdev, pero el patrón de acceso depende de la fragmentación y el recordsize. En un pool tranquilo con registros grandes, los scrub pueden ser discretos. En un pool muy fragmentado con muchos bloques pequeños aleatorios, los scrub se comportan más como una tormenta de lecturas aleatorias a cámara lenta.
Los scrub compiten con tu carga real por:
- Ancho de banda del disco e IOPS
- Profundidad de cola del HBA/controlador
- ARC (caché) y ancho de banda de memoria
- CPU (checksumming, descompresión, paridad)
Si tu pool es RAIDZ y la CPU es débil, el checksumming más la reconstrucción de paridad puede ser más caro de lo que esperas. En CPUs modernas suele ir bien. En cajas “compramos lo más barato que arranca”, se complica.
Qué se verifica
El scrub comprueba bloques asignados, no espacio libre. Valida tanto metadatos como bloques de datos. Si tienes snapshots, el scrub cubre los bloques referenciados por snapshots también, porque esos bloques siguen asignados. Por eso los scrub en pools con muchos snapshots pueden tardar una eternidad: pediste a ZFS que conservara bloques antiguos, y los va a verificar.
Por qué importan los scrub aunque “nunca leas datos antiguos”
Los lees. Quizá no hoy, pero la primera vez que necesites esos datos antiguos suele ser el peor momento para descubrir que están rotos. Los scrub convierten “descubrimos la corrupción durante un incidente” en “descubrimos la corrupción un martes por la mañana y la arreglamos antes de que alguien lo notara.” Esa diferencia cambia una trayectoria profesional entera.
Qué scrubear (y qué no confundir con scrubbing)
Haz scrub al pool. No a un dataset. No a un directorio. La integridad en ZFS es una propiedad a nivel de pool. Tu unidad de verdad es zpool.
Objetivos de scrub: la lista práctica
- Pools de producción con redundancia (mirrors/RAIDZ): haz scrub regularmente. Quieres reparación automática cuando aún sea reparable.
- Pools de backup: haz scrub aún más religiosamente. Las copias de seguridad que no se verifican son solo archivos optimistas.
- Pools de disco único: los scrub todavía detectan corrupción, pero no finjas que la “arreglan”. Combínalos con buenas copias de seguridad y preferiblemente añade redundancia.
- Almacenamiento en frío con lecturas infrecuentes: los scrub son tu única ruta rutinaria de lectura. Sin scrub, estás a un “día de restauración” de arrepentimiento.
No confundas esto con scrubbing
- Pruebas SMART validan señales de salud del disco, no la corrección end-to-end de tus datos.
- RAID patrol read (RAID hardware) lee stripes pero normalmente no puede validar la corrección visible por la aplicación.
- Comprobaciones de sistema de archivos en archivos no-ZFS suelen validar consistencia de metadatos, no la corrección de datos.
- Backups no son verificación a menos que realmente pruebes la restauración o al menos verifiques checksums en los objetos guardados.
Cuándo ejecutar scrubs: calendarios que sobreviven al contacto con la realidad
La gente pregunta por la cadencia “correcta” de scrub. No existe una única. Solo existe una cadencia que se ajuste a tu tolerancia al riesgo, temperatura de datos, tamaño de dispositivos y presupuesto operativo.
Aquí tienes la línea base opinada que funciona en la mayoría de equipos:
- Pools de producción de propósito general: scrub mensual.
- Pools de backup/archivado: scrub mensual, a veces quincenal si el pool es grande y el RTO de restauración importa.
- Bases de datos de alta rotación y clusters de VM: scrub mensual, pero controla el impacto (ventanas fuera de pico, tunning, monitorización). Si el mensual es demasiado disruptive, arregla la capacidad I/O subyacente—no dejes de verificar.
- Pools muy grandes (cientos de TB+): la frecuencia debe considerar la duración del scrub. Si los scrub tardan 20 días, “mensual” se vuelve una comedia. Quizá necesites aumentar throughput, reducir churn de snapshots o separar cargas.
Dos restricciones importan más que los calendarios:
- Tiempo de detección vs. tiempo de fallo. Si tienes sectores latentes acumulándose, quieres descubrirlos antes de que falle otro disco y la redundancia quede comprometida.
- Tiempo de finalización del scrub. Un scrub que nunca termina es un ritual, no un control.
Los scrub también interactúan con el riesgo de resilver. Si pospones scrub durante un año y luego pierdes un disco, el resilver leerá enormes cantidades de datos, y ahí es cuando aparecen errores latentes. Mejor encontrar y reparar errores latentes durante un scrub mientras el pool está sano.
Broma #2: Saltarse los scrub porque “rendimiento” es como saltarse la limpieza dental por “falta de tiempo.” Igual pagarás, pero con más gritos.
Cuándo evitar iniciar un scrub
- Poco antes de una gran migración, simulacro de restauración o reequilibrado de datos.
- Durante periodos conocidos de rendimiento degradado (reconstrucciones, resilvers, replicación intensa).
- Cuando ya te falta redundancia (pool degradado). En ese caso, decide deliberadamente: scrubbing un pool degradado puede estresar los discos restantes, pero también puede revelar bloques ilegibles temprano. Hazlo con consciencia.
Tareas prácticas: comandos, salidas y decisiones (12+)
Todo lo siguiente está pensado para ser copiado y pegado. La clave no es el comando. La clave es la decisión que tomas después de ejecutarlo.
Task 1: Check overall pool health and the last scrub result
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
status: One or more devices has experienced an error resulting in data corruption.
action: Restore the file in question if possible. Otherwise restore the entire pool from backup.
scan: scrub repaired 0B in 03:12:41 with 2 errors on Sun Feb 4 02:11:03 2026
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
errors: Permanent errors have been detected in the following files:
tank/data/app.db
Qué significa: El pool está ONLINE, pero ZFS encontró errores permanentes en un archivo. “Repaired 0B” indica que no pudo curar esos bloques desde la redundancia, o que los bloques dañados estaban en metadata de una forma que impidió la reparación.
Decisión: Trátalo como un incidente para ese dataset. Restaura el objeto afectado desde una fuente conocida (backup, snapshot en otra ubicación). Si esto es un mirror y sigue sin poder repararse, sospecha que la corrupción se escribió de forma consistente, o que ambos lados tienen el mismo bloque malo.
Task 2: Start a scrub (and know what you just did)
cr0x@server:~$ sudo zpool scrub tank
Qué significa: Has indicado a ZFS que comience a escanear los bloques asignados y verificar checksums.
Decisión: Inicia scrubs en una ventana controlada a menos que estés respondiendo a sospecha de corrupción. Si lo inicias durante la carga pico, no te sorprendas por los gráficos.
Task 3: Monitor scrub progress
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
scan: scrub in progress since Mon Feb 4 01:13:22 2026
1.20T scanned at 824M/s, 620G issued at 415M/s, 8.40T total
0B repaired, 7.38% done, 05:20:11 to go
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
errors: No known data errors
Qué significa: “Scanned” vs “issued” importa. Scanned es progreso lógico; issued es I/O real despachado. Si issued está muy por detrás, algo está limitando I/O o el scrub está compitiendo con la carga.
Decisión: Si la ETA se dispara o la tasa de issued colapsa durante horas laborales, considera pausar y reprogramar, o aborda la contención (ver guía de diagnóstico).
Task 4: Pause a scrub (because production exists)
cr0x@server:~$ sudo zpool scrub -p tank
Qué significa: El scrub queda en pausa y puede reanudarse más tarde. (El soporte depende de la implementación de ZFS; en OpenZFS es común.)
Decisión: Si pausas scrubs rutinariamente, probablemente no tienes suficiente capacidad I/O. Arregla eso, o acabarás dejando de scrappear por completo.
Task 5: Stop a scrub (the blunt instrument)
cr0x@server:~$ sudo zpool scrub -s tank
Qué significa: Detiene el scrub. Se pierde el progreso; el próximo inicio comenzará de nuevo.
Decisión: Deténlo solo si es necesario. Prefiere pausar/reanudar cuando esté disponible.
Task 6: Identify which vdev/device is producing checksum errors
cr0x@server:~$ zpool status -v tank
pool: tank
state: DEGRADED
status: One or more devices could not be used because the label is missing or invalid.
scan: scrub repaired 32M in 02:40:11 with 0 errors on Sun Feb 2 03:02:11 2026
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
sda ONLINE 0 0 18
sdb UNAVAIL 0 0 0 cannot open
errors: No known data errors
Qué significa: sda está devolviendo datos malos (errores CKSUM). sdb no está disponible. Estás operando sin redundancia y el disco restante ya inspira desconfianza.
Decisión: Esta es una situación de “dejar de hacer I/O no esencial”. Restaura la redundancia inmediatamente. También obtén datos SMART de sda y revisa cableado/HBA. Un error de checksum suele ser un problema de camino, no solo del disco.
Task 7: Map device names to physical disks (avoid replacing the wrong one)
cr0x@server:~$ ls -l /dev/disk/by-id/ | grep -E 'sda|sdb'
lrwxrwxrwx 1 root root 9 Feb 4 01:22 ata-SAMSUNG_MZ7LM960HAJM_S3Z9NX0K123456 -> ../../sda
lrwxrwxrwx 1 root root 9 Feb 4 01:22 ata-SAMSUNG_MZ7LM960HAJM_S3Z9NX0K654321 -> ../../sdb
Qué significa: Puedes identificar el modelo/serial asociado a cada nodo de dispositivo. La nomenclatura de dispositivos en ZFS debería usar IDs estables cuando sea posible.
Decisión: Usa rutas /dev/disk/by-id en la configuración del pool de ahora en adelante. Al reemplazar, empareja por número de serie, no por esperanza.
Task 8: Pull SMART health and error counters
cr0x@server:~$ sudo smartctl -a /dev/sda
=== START OF INFORMATION SECTION ===
Model Family: Samsung based SSDs
Device Model: SAMSUNG MZ7LM960HAJM-00005
Serial Number: S3Z9NX0K123456
Firmware Version: GXT5204Q
...
SMART overall-health self-assessment test result: PASSED
...
ID# ATTRIBUTE_NAME VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
5 Reallocated_Sector_Ct 100 100 010 Pre-fail Always - 0
187 Reported_Uncorrect 100 100 000 Old_age Always - 2
199 UDMA_CRC_Error_Count 200 200 000 Old_age Always - 38
Qué significa: “PASSED” no es un certificado de salud impecable. UDMA_CRC_Error_Count a menudo apunta a problemas de cableado/backplane/HBA. Reported_Uncorrect significa que el dispositivo ha visto errores no corregibles.
Decisión: Si los errores CRC aumentan, reemplaza cable/backplane/slot, vuelve a conectar o mueve el disco a otro puerto antes de reemplazar la unidad. Si los no corregibles aumentan, planea reemplazar la unidad.
Task 9: Check ZFS error counters over time (baseline matters)
cr0x@server:~$ zpool status -P tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 03:12:41 with 0 errors on Sun Feb 2 03:02:11 2026
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
/dev/disk/by-id/ata-SAMSUNG...123456 ONLINE 0 0 1
/dev/disk/by-id/ata-SAMSUNG...654321 ONLINE 0 0 0
errors: No known data errors
Qué significa: Hay 1 error de checksum en un lado del mirror. Un solo error puede ser histórico o una tendencia actual.
Decisión: Registra los contadores ahora y revísalos después del próximo scrub y tras I/O intenso. Si el contador se mueve, investiga camino y dispositivo. Si se mantiene estable por semanas, pudo haber sido transitorio—pero sigue vigilando.
Task 10: See pool and vdev properties that impact scrub behavior
cr0x@server:~$ zpool get all tank | egrep 'ashift|autoreplace|autotrim|failmode|autoexpand'
tank ashift 12 local
tank autoexpand off default
tank autoreplace off default
tank autotrim on local
tank failmode wait default
Qué significa: ashift=12 (sectores de 4K) es típico. autotrim afecta comportamiento de SSD. No son perillas de scrub directamente, pero influyen en amplificación de escritura, flujos de reemplazo y estabilidad del rendimiento del dispositivo.
Decisión: Si usas SSD, mantén autotrim=on salvo que tengas una razón para no hacerlo. Para automatización de reemplazos, considera autoreplace con cuidado—la automatización es genial hasta que reemplaza lo equivocado con seguridad.
Task 11: Check dataset settings that amplify scrub pain (compression, recordsize, snapshots)
cr0x@server:~$ zfs get -o name,property,value -s local,received recordsize,compression,atime tank/data
NAME PROPERTY VALUE
tank/data compression lz4
tank/data recordsize 128K
tank/data atime off
Qué significa: Defaults razonables: compresión LZ4, recordsize 128K, atime off. Un recordsize más pequeño en imágenes VM puede aumentar metadata y fragmentación, afectando el comportamiento del scrub.
Decisión: Para zvols/datasets de VM, ajusta recordsize/volblocksize deliberadamente. No culpes a los scrub por un layout que tú creaste.
Task 12: Find out whether errors are tied to a specific file
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:58:03 with 1 errors on Sun Feb 2 03:02:11 2026
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
errors: Permanent errors have been detected in the following files:
tank/data/logs/2026-01-17.gz
Qué significa: ZFS a veces puede nombrar el archivo afectado. No siempre, pero cuando puede, acéptalo como un regalo.
Decisión: Restaura o regenera ese archivo. Para logs puedes aceptar la pérdida; para bases de datos, no. En cualquier caso, trátalo como una señal para investigar el dispositivo/camino subyacente.
Task 13: Verify whether redundancy can heal by forcing reads
cr0x@server:~$ sudo dd if=/tank/data/logs/2026-01-17.gz of=/dev/null bs=1M status=progress
104857600 bytes (105 MB, 100 MiB) copied, 0.42 s, 249 MB/s
Qué significa: Una lectura directa puede disparar la verificación del checksum. Si el bloque está corrupto y existe redundancia, ZFS puede reparar en lectura (dependiendo de la configuración y la ruta de acceso).
Decisión: Si la lectura lanza errores de I/O o el archivo no se puede leer, necesitas restaurar desde backup o snapshot. No intentes “cat” para salir de una corrupción real.
Task 14: Inspect I/O pressure during a scrub (Linux example)
cr0x@server:~$ iostat -x 1 3
Linux 6.6.0 (server) 02/04/2026 _x86_64_ (16 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
12.10 0.00 5.55 18.40 0.00 63.95
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s w_await aqu-sz %util
sda 820.0 345000.0 0.0 0.00 12.40 420.7 5.0 120.0 5.20 10.2 96.0
sdb 790.0 339000.0 0.0 0.00 11.90 429.1 4.0 100.0 4.80 10.0 94.5
Qué significa: Los discos están al máximo (~95% util). La latencia de lectura (~12 ms) puede ser aceptable o desastrosa según tu carga.
Decisión: Si la latencia de producción sufre, programa scrubs fuera de pico, aumenta el número de vdevs (más platos), o separa las cargas. “Simplemente no scrubear” es cómo te conviertes en un ejemplo a seguir… en el mal sentido.
Task 15: Confirm you’re not scrubbing because of phantom time jumps or missed runs
cr0x@server:~$ zpool history -i tank | tail -n 12
2026-02-02.03:02:11 zpool scrub tank
2026-02-02.05:58:14 zpool scrub -s tank
2026-02-03.02:01:00 zpool scrub tank
2026-02-03.06:12:09 zpool scrub -p tank
2026-02-04.01:13:22 zpool scrub tank
Qué significa: Operadores (o automatización) están iniciando/deteniendo scrubs con frecuencia. Eso huele mal: o el calendario es incorrecto, el impacto es demasiado alto, o ambos.
Decisión: Arregla el proceso: define un único propietario (automatización o humanos), establece una ventana fuera de pico y alerta cuando los scrub no se completen.
Guía rápida de diagnóstico: encuentra el cuello de botella pronto
Cuando un scrub es lento o aparecen errores, necesitas responder tres preguntas rápido: ¿Realmente progresa? ¿Está bloqueado por I/O, CPU o algo raro? ¿Vemos corrupción real o errores de transporte?
Primero: ¿Avanza el scrub y crecen los errores?
- Ejecuta
zpool statusdos veces, con 60 segundos de diferencia. - Compara “scanned” y “issued”, y comprueba si los contadores READ/WRITE/CKSUM aumentan.
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
scan: scrub in progress since Mon Feb 4 01:13:22 2026
1.30T scanned at 815M/s, 700G issued at 430M/s, 8.40T total
0B repaired, 8.10% done, 05:10:11 to go
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
errors: No known data errors
Si issued no se mueve: sospecha un dispositivo colgado, cola del controlador atascada, o el sistema está limitando debido a otra carga.
Si los errores están subiendo: deja de tratar esto como ajuste de rendimiento y empieza a tratarlo como triage de integridad de datos.
Segundo: ¿Es IOPS, throughput, CPU o contención?
- Disco saturado:
iostat -xmuestra %util alto y await creciente → estás limitado por I/O o compitiendo con carga. - CPU saturada:
topmuestra uso kernel/system alto, overhead de checksums/paridad, posiblemente compresión/descompresión. Las tasas de scrub pueden caer en RAIDZ con CPU débil. - ARC en churn: la presión de memoria puede causar lecturas extras; revisa
free -hy las herramientas ARC de tu plataforma.
cr0x@server:~$ top -b -n 1 | head -n 15
top - 02:11:08 up 31 days, 6:22, 2 users, load average: 12.44, 10.80, 9.21
Tasks: 312 total, 2 running, 310 sleeping, 0 stopped, 0 zombie
%Cpu(s): 22.0 us, 0.5 sy, 0.0 ni, 70.0 id, 7.5 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 64256.0 total, 3120.4 free, 23120.9 used, 38014.7 buff/cache
MiB Swap: 4096.0 total, 4096.0 free, 0.0 used. 40110.2 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1421 root 20 0 0 0 0 I 18.2 0.0 12:44.21 z_wr_iss
1412 root 20 0 0 0 0 I 14.7 0.0 10:03.88 z_rd_iss
Decisión: Si el CPU está mayormente idle y el iowait alto, estás limitado por almacenamiento. Si la CPU está alta y los discos no, estás limitado por cómputo o por algo que throttlea (por ejemplo cuellos de un solo hilo en hardware antiguo). Cambia una variable a la vez: calendario, layout de vdev y capacidad hardware.
Tercero: ¿Los errores CKSUM son “disco malo” o “camino malo”?
Los errores de checksum pueden ser causados por:
- Corrupción real en el medio del dispositivo
- Cable SATA/SAS malo o expander
- Firmware/driver del HBA inestable
- Inestabilidad de alimentación al disco/backplane
Correlaciona los contadores CKSUM de ZFS con los errores CRC de SMART y los logs del kernel.
cr0x@server:~$ dmesg | egrep -i 'ata|sas|scsi|reset|crc|error' | tail -n 10
[123456.789] ata4: hard resetting link
[123457.012] ata4: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[123457.345] ata4.00: configured for UDMA/133
[123457.678] ata4.00: failed command: READ DMA EXT
[123457.679] ata4.00: status: { DRDY ERR }
[123457.680] ata4.00: error: { ICRC ABRT }
Decisión: Si ves ICRC/CRC errors y reinicios de enlace, sospecha primero del camino. Reemplaza cable, mueve puerto, actualiza firmware del HBA. Los discos cargan con muchos pecados que no cometieron.
Tres mini-historias corporativas del mundo real
Mini-historia 1: El incidente causado por una suposición errónea
La compañía ejecutaba una gran plataforma de datos que desde lejos parecía moderna: contenedores, service mesh y dashboards por todas partes. El almacenamiento estaba “resuelto” por un par de pools ZFS en mirror por nodo. Tenían una “semana de mantenimiento” trimestral donde alguien corría un scrub si se acordaba. Mayormente, no lo hacían.
La suposición errónea era simple: “Los mirrors nos protegen de fallos de disco, y la app replica los datos de todos modos.” El mirror fue tratado como una manta de confort tipo RAID1, no como un sistema de integridad de datos. Nadie preguntó qué tan rápido se detectaría la corrupción, ni qué pasaría si un bloque malo existía en ambos lados del mirror porque la corrupción se introdujo antes de que la escritura llegara a disco.
Entonces llegó una petición de restauración—nada dramático. Un equipo quería un dataset antiguo para volver a entrenar. El trabajo falló con errores de checksum en un puñado de bloques. Los ingenieros hicieron lo que hacen bajo presión: reintentaron, reiniciaron, movieron la carga. Los errores se movieron con ello.
Eventualmente, alguien ejecutó zpool status -v y vio errores permanentes en archivos que no se habían leído en meses. El pool estaba técnicamente “ONLINE”, así que la monitorización había estado tranquila. El mirror había estado sirviendo silenciosamente bloques corruptos porque nadie forzó la verificación de datos fríos. Un scrub mensual lo habría encontrado a tiempo para repararlo desde la redundancia o desde snapshots que aún existieran. En cambio, las copias restantes eran idénticas y erróneas.
La lección no fue “ZFS falló.” ZFS hizo exactamente lo que prometía: detectó la corrupción. El fallo del sistema fue que la organización trató la verificación como opcional. Los controles de integridad que no se ejercitan son solo creencias con sintaxis de CLI.
Mini-historia 2: La optimización que salió mal
Un proveedor SaaS mediano ejecutaba ZFS en una capa de almacenamiento compartida. Los scrub se programaban mensualmente, pero los ingenieros se quejaban de picos de latencia en bases de datos de clientes. Así que el equipo hizo una “optimización”: aumentaron la frecuencia de scrub a semanal pero los programaron para horas laborales con menor prioridad de I/O a nivel OS y dejaron que el scrub “tarde lo que tarde”.
En teoría sonaba responsable: scrubs constantes y suaves en lugar de un gran evento mensual. En la práctica se convirtió en ruido de fondo permanente. El scrub nunca terminaba antes de la siguiente ejecución programada. Los operadores se acostumbraron a ver “scrub in progress” como estado normal, así que nadie notó cuando las tasas de scrub cayeron un 80% tras un HBA que empezó a loggear reinicios de enlace.
Semanas después, un disco falló. Comenzó el resilver en hardware ya estresado. El pool estaba reconstruyendo mientras un scrub seguía ejecutándose porque nadie lo detuvo. La latencia subió, aparecieron timeouts y el incidente se volvió visible para clientes. La causa raíz no fue “scrubs semanales” por sí sola. Fue la combinación de scrubs que no terminan, la normalización de un estado anómalo y controles insuficientes durante estados degradados.
Después cambiaron la regla: un scrub debe completarse dentro de una ventana definida, y no se ejecuta ningún scrub mientras el pool está degradado o en resilvering salvo aprobación explícita. También añadieron alertas para “scrub corriendo más de X” y “throughput de scrub por debajo de Y durante Z minutos.” La optimización exitosa no fue tunear; fue poner límites al trabajo.
Mini-historia 3: La práctica aburrida pero correcta que salvó el día
Una compañía del ámbito financiero tenía reputación de operaciones conservadoras. Poco emocionante. Poco fashion. Pero ejecutaban scrubs mensuales en todos los pools ZFS, y tenían un runbook pequeño que requería que los operadores registraran: última vez de scrub, bytes reparados y contadores de errores de dispositivos. También hacían simulacros trimestrales de restauración para una muestra aleatoria de datasets. La gente protestaba que era papeleo. Lo era. Ese era el punto.
Un mes, un scrub reparó una pequeña cantidad de datos en un pool RAIDZ2—nada masivo, pero no cero. Los contadores mostraron algunos errores de checksum aislados a un solo dispositivo. SMART se veía “bien”. Porque llevaban tendencias registradas, pudieron ver que el contador de checksum había aumentado desde el mes anterior. Reemplazaron el cable primero. Los errores continuaron. Reemplazaron la unidad en la siguiente ventana de mantenimiento.
Dos semanas después, otra unidad en el mismo vdev empezó a tirar errores de lectura. Si la primera unidad no se hubiera reemplazado proactivamente, habrían estado en un RAIDZ2 con dos dispositivos marginales durante una ventana de reconstrucción—justo cuando emergen errores latentes. En cambio, el pool mantuvo salud, los scrub siguieron limpios y el incidente nunca ocurrió.
No pasó nada heroico. No hubo war room nocturno. No hubo escaladas ejecutivas. Solo un bucle de retroalimentación mundano: scrub, registrar, reaccionar. Lo aburrido es una característica en ingeniería de almacenamiento.
Errores comunes: síntoma → causa raíz → solución
1) “Pool is ONLINE, so we’re fine”
Síntoma: Todo parece verde, pero más tarde ves errores permanentes en archivos antiguos.
Causa raíz: ONLINE solo significa que el pool es accesible. No significa que todos los datos sean actualmente legibles y correctos.
Solución: Ejecuta scrub regularmente y alerta sobre cualquier línea errors: en zpool status, no solo sobre el estado del pool. Integra resultados de scrub en la monitorización.
2) Scrubs nunca terminan
Síntoma: zpool status siempre muestra “scrub in progress”, la ETA no tiene sentido, los operadores lo ignoran.
Causa raíz: No hay suficiente capacidad I/O; scrub programado con demasiada frecuencia; retención masiva de snapshots; fragmentación; contención con la carga.
Solución: Aplica un SLO de finalización: el scrub debe terminar dentro de X horas/días. Reduce churn de snapshots, aumenta paralelismo de vdev, programa fuera de pico o separa pools por carga.
3) Rising CKSUM errors on one device but SMART says PASSED
Síntoma: zpool status muestra incrementos de CKSUM; SMART overall health dice PASSED.
Causa raíz: A menudo transporte: cable malo, HBA inestable, problemas de backplane o expander. SMART no es la verdad absoluta sobre integridad de datos.
Solución: Revisa UDMA_CRC_Error_Count (SATA), logs del kernel para reinicios de enlace, reconecta/reemplaza cable, mueve puertos, actualiza firmware del HBA. Reemplaza la unidad si los errores persisten.
4) “We scrubbed and it repaired stuff; we’re done”
Síntoma: El scrub reparó bytes; el equipo se encoge de hombros y sigue.
Causa raíz: Un evento de reparación es una alarma de humo, no una vuelta de victoria. Algo devolvió datos incorrectos.
Solución: Investiga qué dispositivo/vdev vio errores; correlaciona con SMART y logs; ejecuta un scrub adicional tras cambios para confirmar estabilidad.
5) Scrubbing a degraded pool without thinking
Síntoma: El rendimiento colapsa; dispositivos adicionales fallan durante scrub/resilver.
Causa raíz: Lecturas extra en discos ya estresados; scrub compite con resilver; las ventanas de reconstrucción amplifican errores latentes.
Solución: Por defecto: evita scrubs durante resilver a menos que estés buscando corrupción sospechada. Prioriza restaurar redundancia. Si haces scrub en degradado, hazlo intencionalmente con monitorización y plan de rollback.
6) Confusing application corruption with storage corruption
Síntoma: Inconsistencias lógicas en la base de datos; ZFS reporta scrubs limpios.
Causa raíz: La app escribió datos malos, o hubo un bug/issue en la capa de aplicación. ZFS lo almacenó fielmente.
Solución: Usa checks a nivel de aplicación, backups e snapshots inmutables con retención. ZFS es necesario, no suficiente, para corrección.
7) Scrub schedule copied from a blog, not from your pool reality
Síntoma: Los scrubs causan impacto repetido en clientes o se desactivan.
Causa raíz: El calendario no coincide con el número de dispositivos, tamaño del pool y la carga del negocio.
Solución: Empieza con mensual, luego mide duración e impacto. Ajusta la ventana y el headroom de throughput. Trata el scrub como un control obligatorio, no una tarea opcional.
Listas de verificación / plan paso a paso
Plan base para un nuevo pool ZFS (orientado a producción)
- Elige redundancia intencionalmente: mirrors para IOPS y curación simple; RAIDZ2/3 para capacidad y tolerancia a fallos.
- Nombra dispositivos por ID estable: construye pools usando rutas
/dev/disk/by-id. - Establece cadencia de scrub: mensual por defecto; confirma que puede completarse dentro de tu ventana.
- Decide retención de snapshots: conserva lo que puedas permitirte scrappear. El sprawl de snapshots es real.
- Monitorización: alerta sobre (a) scrub no ejecutado en N días, (b) scrub reparó bytes > 0, (c) cualquier nuevo error READ/WRITE/CKSUM, (d) pool DEGRADED/FAULTED, (e) scrub tomando demasiado tiempo.
- Ejecuta un scrub de prueba tras el go-live: mide throughput e impacto; registra duración base.
Rutina mensual de operaciones (aburrida, repetible, correcta)
- Ejecuta
zpool statusy registra contadores. - Ejecuta/confirma finalización de scrub.
- Revisa resultado del scrub: bytes reparados, conteo de errores, duración.
- Extrae resúmenes SMART de todos los dispositivos; busca errores CRC/link y sectores reallocados/pending.
- Verifica al menos una ruta de restauración: un drill de restauración de un dataset pequeño o verificación de checksums contra artefactos conocidos.
Rutina de incidente cuando ves errores de checksum
- No escribir en pánico: evita escrituras pesadas que churnen metadata y compliquen la recuperación.
- Captura estado: guarda
zpool status -v, extractos dedmesgy reportes SMART. - Identifica alcance: errores permanentes a nivel de archivo vs solo contadores de dispositivo.
- Estabiliza el camino de hardware: cables/puertos/HBA.
- Restaura redundancia: reemplaza dispositivos fallados/no disponibles.
- Scrub de nuevo: confirma que los errores dejan de aumentar y el scrub completa limpio.
- Restaura objetos afectados: desde backup/snapshot; verifica integridad.
Datos interesantes y contexto histórico
- Dato 1: ZFS se diseñó en Sun Microsystems con el objetivo explícito de integridad de datos end-to-end, no solo gestión de capacidad.
- Dato 2: El RAID tradicional verifica paridad pero típicamente no valida que los datos devueltos sean los mismos que el sistema de archivos escribió originalmente.
- Dato 3: ZFS almacena checksums en metadata padre, así que el checksum de un bloque no está en el mismo sector que el propio bloque.
- Dato 4: El copy-on-write hace que ZFS nunca sobrescriba datos vivos in situ; escribe nuevos bloques y luego cambia punteros, reduciendo riesgos de “torn write”.
- Dato 5: El scrub verifica bloques asignados, incluidos los retenidos por snapshots; la retención de snapshots impacta directamente la carga de scrub.
- Dato 6: “Auto-reparación” requiere redundancia; un pool de disco único puede detectar corrupción pero no repararla.
- Dato 7: Errores de checksum pueden venir de la capa de transporte (cables/HBA), no solo del medio del disco—SMART “PASSED” no contradice eso.
- Dato 8: Resilver y scrub son escaneos diferentes: resilver es reconstrucción dirigida tras eventos de dispositivo; scrub es verificación completa del contenido del pool.
- Dato 9: Discos de gran capacidad amplían la ventana de tiempo en que los errores latentes importan, porque la lectura para rebuild/scrub abarca más datos y tarda más.
FAQ
1) How often should I scrub a ZFS pool?
Monthly is the default that works in most environments. If your scrub can’t finish monthly, fix headroom/snapshot sprawl or adjust architecture—don’t abandon verification.
2) Does a ZFS scrub check free space?
No. It checks allocated blocks reachable from the metadata tree, including snapshot-referenced blocks. Free space isn’t scanned because there’s nothing to verify.
3) What’s the difference between scrub and resilver?
Scrub is a full integrity scan of allocated data/metadata. Resilver reconstructs data onto a replaced/returned device for the affected vdev(s), typically only the blocks in use.
4) If I have mirrors, do I still need scrubs?
Yes. Mirrors give you a second copy, but without scrubs you may not discover corruption until you read the block during an incident—or during a resilver when you’re already stressed.
5) Can ZFS fix corruption automatically?
If redundancy exists and at least one copy is good, ZFS can repair a bad copy during scrub (and sometimes during normal reads). If all copies are wrong, it can only detect.
6) Why do I see CKSUM errors but no READ/WRITE errors?
Because the device returned data successfully, but the data didn’t match the stored checksum. That points to silent corruption or to transport issues (cable/HBA/backplane).
7) Are scrubs dangerous for disk health?
They increase read load, which can expose marginal drives. That’s not a reason to avoid scrubs; it’s a reason to find weak drives on your schedule, not during a failure.
8) Should I scrub SSD pools differently than HDD pools?
The integrity goal is the same. SSDs often scrub faster due to random-read strength, but they can still have firmware and path issues. Keep scrubs regular and monitor wear/SMART.
9) My scrub repaired bytes. Is that normal?
It can happen, but it shouldn’t be routine. Treat “repaired” as an integrity event: identify the device path, check logs/SMART, and confirm the next scrub is clean.
10) Do I need ECC RAM for ZFS integrity?
ECC is strongly recommended for systems where data correctness matters. ZFS can detect on-disk corruption, but it can’t reliably detect corruption introduced in RAM before checksums are computed.
Conclusion: next steps you can do this week
Si ejecutas ZFS y no estás haciendo scrubs, confías en que tu pila de almacenamiento será perfecta para siempre. Eso es adorable. Además, por favor no lo hagas.
- Configura un calendario de scrub (mensual por defecto) y asegúrate de que se complete.
- Añade alertas para: scrub vencido, scrub reparó bytes > 0, cualquier nuevo error READ/WRITE/CKSUM y tiempo de ejecución de scrub que exceda tu ventana.
- Ejecuta un scrub ahora durante una ventana controlada, luego registra duración y throughput como baseline.
- Cuando veas errores de checksum, correlaciónalos con SMART CRC/reinicios de enlace antes de reemplazar hardware a ciegas.
- Prueba restauraciones para al menos un dataset representativo. Los scrub verifican lo que está allí; los drills de restauración verifican que puedas recuperar cuando no lo está.
El objetivo no es “confiar en ZFS.” El objetivo es operacionalizar la verificación. Los scrub son la parte donde dejas de creer y empiezas a saber.