ZFS Scrub: con qué frecuencia hacerlo y qué demuestra

¿Te fue útil?

Tu pool ZFS parece estar bien. Las aplicaciones están contentas. SMART muestra “PASSED”. Entonces un disco muere, empieza un resilver y, de repente, descubres que conviviste con corrupción silenciosa durante meses.
Ese momento es cuando la gente aprende para qué sirve un scrub.

Un scrub no es una “tarea de rendimiento”. No es un ritual. Es una forma controlada y repetible de demostrar que tu pool aún puede leer lo que piensa que escribió—antes de que necesites esa prueba en medio de una interrupción.

Qué hace realmente un scrub (y qué no hace)

Un scrub de ZFS es un recorrido completo de integridad del pool. ZFS lee todos los bloques asignados, verifica checksums y—si existe redundancia—repara datos malos reescribiendo copias buenas.
Esa es la clave: el scrub es una pasada de verificación de lectura con sanación opcional.

Qué hace el scrub

  • Lee datos asignados a través de datasets/zvols/snapshots, no el espacio libre.
  • Verifica checksums de extremo a extremo (el checksum en ZFS se almacena separado de los datos, así que “el disco devolvió algo” no es suficiente).
  • Repara cuando es posible usando paridad/copias espejo y reescribiendo bloques corregidos (una lectura “autocurativa”).
  • Saca a la luz errores latentes de sectores y rutas inestables que las cargas normales podrían no tocar.
  • Acumula evidencia: contadores de errores, vdevs afectados y si la corrupción es permanente (sin copia buena) o corregible.

Qué no hace el scrub

  • No valida la semántica de tu aplicación. Si tu app escribió bytes incorrectos de forma consistente, ZFS los preservará con orgullo.
  • No prueba que las copias de seguridad sean restaurables. El scrub no es una prueba de restauración.
  • No arregla un “diseño de hardware defectuoso”. Si tu HBA, expander o backplane mienten, el scrub puede revelar síntomas pero no curar la causa.
  • No necesariamente lee el espacio libre. La corrupción del espacio libre es mayormente irrelevante hasta la asignación, y ZFS no gasta tiempo validando bloques que no existen.

El scrub tampoco es un resilver. Un resilver reconstruye datos faltantes para un disco reemplazado o un dispositivo vuelto a conectar. Un scrub valida datos existentes y los sana si la redundancia lo permite.
Confundir ambos conduce a algunos incidentes creativos.

Chiste #1: Un scrub es como usar hilo dental—nadie lo disfruta, y todo el mundo jura que lo hará más seguido después de que algo empiece a sangrar.

Qué demuestra el scrub (y qué solo sugiere)

Operaciones es el arte de saber qué pueden demostrar tus herramientas. El scrub te da evidencia sólida, pero no omnisciencia.
Trata los resultados del scrub como una señal de fiabilidad con límites.

El scrub demuestra estas cosas (con alta confianza)

  • ZFS puede leer bloques asignados y validarlos contra checksums en el momento del scrub. Si el scrub se completa limpio, los datos del pool tal como se leyeron coincidieron con los checksums registrados.
  • Las rutas de redundancia pueden entregar datos correctos para bloques que estaban mal en un dispositivo. El conteo de “reparados” significa que ZFS tenía al menos una copia buena y la reescribió.
  • Tu sistema puede sostener una carga de lectura secuencial de pool completo sin colapsar. Esto importa porque los resilvers y las restauraciones se ven similares desde la perspectiva del almacenamiento.

El scrub sugiere estas cosas (útiles, pero no garantizados)

  • Salud del medio del disco. Un scrub limpio sugiere que el medio está bien ahora, pero no predice fallos futuros. Los discos fallan cualquier día de la semana.
  • Integridad del controlador/cable. Si aparecen errores durante el scrub, la ruta es sospechosa. Si nunca aparecen errores, tampoco es un certificado de cableado bueno—solo falta de fallos observados.
  • Márgenes de seguridad de la carga de trabajo. La velocidad y latencia del scrub revelan contención, pero un “scrub rápido” no significa que tu carga de I/O aleatoria esté segura bajo presión.

Qué no puede demostrar

  • Que los datos sean “correctos” para los humanos. ZFS valida integridad, no significado. Si guardaste la hoja de cálculo equivocada, la protegerá fielmente.
  • Que un resilver futuro vaya a tener éxito. El scrub reduce la probabilidad de descubrir errores latentes durante un resilver, pero no puede eliminar fallos múltiples, bugs de firmware o tormentas de URE súbitas.

Un modelo mental útil: el scrub responde “¿Puedo leer todo lo que me importa ahora mismo, y si no, puedo arreglarlo con la redundancia?”
Esa es una muy buena pregunta. También no es la única que debes hacerte.

Una cita útil para mantener en tu runbook, porque es dolorosamente cierta:
“La esperanza no es una estrategia.” — General Gordon R. Sullivan

Con qué frecuencia ejecutar un scrub: reglas que funcionan en producción

La “frecuencia correcta” del scrub es un compromiso de ingeniería entre latencia de detección y coste operativo.
La latencia de detección es cuánto tiempo estás dispuesto a llevar corrupción silenciosa antes de encontrarla. El coste operativo es el impacto en rendimiento, desgaste y atención humana.

Mi recomendación por defecto (y por qué)

  • Hogar / NAS pequeño: scrub mensual.
  • Pools de ficheros y VMs para empresas: cada 2–4 semanas, inclinándose hacia 2 semanas para pools más grandes.
  • Datos críticos + snapshots de larga retención: cada 1–2 semanas.
  • Archivo / almacenamiento frío: mensual a trimestral, pero solo si además haces simulacros de restauración periódicos y mantienes discos de repuesto compatibles.

Si eso suena agresivo, recuerda lo que compras: descubrimiento temprano de corrupción y detección anticipada de discos marginales.
El scrub más caro es el que no ejecutaste antes de que un fallo de disco te obligara a actuar.

Las dos variables que deberían cambiar realmente tu calendario

1) Tamaño del pool y matemáticas de reconstrucción

Pools más grandes tardan más en scrubear. Scrubs más largos significan una ventana mayor en la que otro fallo puede coincidir con “ya estamos estresados”.
Además, los tiempos de reconstrucción escalan con la capacidad y el comportamiento del dispositivo bajo carga. Si el resilver tarda días, deberías hacer scrubs más a menudo, no menos, porque quieres encontrar errores latentes mientras aún tienes redundancia.

2) Tu churn de datos y retención de snapshots

El scrub lee bloques asignados, incluidos los referenciados solo por snapshots. La retención larga de snapshots incrementa los “datos asignados” incluso si los datasets activos son pequeños.
Si guardas meses de snapshots, cargas más bloques históricos que necesitan verificación periódica. De lo contrario aprendes sobre corrupción antigua justo cuando necesitas restaurar datos antiguos. Ese no es un tipo de sorpresa divertido.

¿Y las SSD? ¿Debo hacer menos scrubs?

No. Podrías hacer scrubs al menos con la misma frecuencia, porque las SSD fallan de maneras que parecen limpias hasta que no lo son.
Las SSD también tienen corrección interna de errores que puede enmascarar un deterioro de NAND hasta que la unidad cae por un precipicio.
El scrub es tu forma de pedirle a toda la pila, de extremo a extremo, que demuestre que aún puede leer y validar checksums.

Impacto en el rendimiento: no lo temas, gestionalo

El scrub compite por I/O. En pools HDD, a menudo se convierte en una gran lectura secuencial que aún perturba la latencia aleatoria.
En cargas mixtas (VMs más scrub), los usuarios no se quejan del throughput; se quejan de picos de latencia.

La respuesta rara vez es “nunca hacer scrub.” La respuesta es “hacer scrub con guardarraíles”: programación, limitación y monitorización. Puedes hacer que los scrubs sean aburridos. Ese es el objetivo.

Scrubs basados en desencadenantes (además de un calendario)

Los scrubs programados son higiene básica. Los scrubs desencadenados son para eventos de riesgo específicos:

  • Después de reemplazar un disco y terminar el resilver, ejecuta un scrub para validar el nuevo estado estable.
  • Después de mover hardware (nuevo HBA/backplane/cables), ejecuta un scrub para detectar problemas de ruta.
  • Después de eventos de energía o actualizaciones de kernel/controladores de almacenamiento, ejecuta un scrub en una ventana de bajo tráfico.
  • Después de que aparezca cualquier error de checksum distinto de cero, haz el scrub pronto, no tarde, después de estabilizar el sistema.

Datos interesantes e historia: por qué existe el scrubbing

El scrubbing no surgió porque los ingenieros estaban aburridos. Existe porque el almacenamiento miente—en silencio, y a veces de forma convincente.
Algunos puntos de contexto que importan cuando defines políticas:

  1. ZFS fue diseñado con checksums de extremo a extremo desde el principio (era Sun), porque los controladores y discos pueden devolver lecturas “exitosas” con datos erróneos.
  2. El término “scrub” existía antes de ZFS en almacenamiento: arrays RAID y SANs empresariales usaban lecturas de patrulla para descubrir errores latentes de sector antes de reconstrucciones.
  3. Los errores latentes de sector se volvieron una preocupación general a medida que las capacidades de disco superaron los tiempos de reconstrucción; cuanto más larga la reconstrucción, más probable es toparse con un bloque malo durante ella.
  4. ZFS almacena checksums separados del bloque que protegen (en metadatos), evitando la falla “la corrupción también corrompe el checksum” común en diseños más débiles.
  5. ZFS solo puede reparar cuando existe redundancia. Un pool de disco único puede detectar discrepancias de checksum, pero no puede conjurar datos correctos.
  6. El scrub también lee snapshots porque los snapshots referencian bloques antiguos; esto es tanto un beneficio (verificación) como un coste (más que leer).
  7. Algunos errores son “corregibles” y otros son permanentes. Esta distinción es operativamente enorme: errores corregibles suelen apuntar a un dispositivo o ruta fallando; errores permanentes significan pérdida de datos salvo restauración desde backup.
  8. Los scrubs son intencionalmente interrumpibles (pausar/detener y reanudar según la implementación), reconociendo las ventanas reales de producción.
  9. Las implementaciones modernas de ZFS exponen ajustables para limitar el impacto del scrub, reflejando el cambio de “ventanas de mantenimiento de gran hierro” a “sistemas siempre activos y multiinquilino”.

Tareas prácticas: comandos, salidas y decisiones

Esta sección es deliberadamente práctica: comandos que puedes ejecutar, qué implica la salida y qué decisión tomar a continuación.
Si solo hojeas una parte, hojea esta.

Tarea 1: Confirmar la salud del pool antes de hacer scrub

cr0x@server:~$ zpool status
  pool: tank
 state: ONLINE
  scan: none requested
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          mirror-0                  ONLINE       0     0     0
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0

errors: No known data errors

Significado: El pool está online; no hay escaneos en curso; los contadores de errores están en cero.
Decisión: Seguro para iniciar un scrub. Si el pool estuviera DEGRADED, decidirías si el scrub es urgente (para encontrar más errores) o arriesgado (para estresar los dispositivos restantes).

Tarea 2: Iniciar un scrub (y saber qué toca)

cr0x@server:~$ sudo zpool scrub tank

Significado: ZFS comienza a leer bloques asignados en tank.
Decisión: Hazlo en una ventana donde el I/O añadido sea aceptable. Si esto es un host de VMs a las 10:00 del lunes, acabas de ofrecerte voluntario para retroalimentación de usuarios.

Tarea 3: Vigilar progreso del scrub y estimar tiempo restante

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
  scan: scrub in progress since Mon Dec 23 01:12:43 2025
        3.21T scanned at 612M/s, 1.04T issued at 198M/s, 18.7T total
        0B repaired, 5.57% done, 1 days 02:11:09 to go
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          mirror-0                  ONLINE       0     0     0
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0

errors: No known data errors

Significado: “Scanned” puede adelantar a “issued” según la contabilidad; céntrate en la tasa de issued y en las tendencias del ETA. Repaired es 0, bien.
Decisión: Si el ETA se dispara durante horas hábiles, considera limitar mediante tunables del sistema, mover la ventana de scrub o pausar (ver tareas posteriores).

Tarea 4: Detectar si el scrub compite con tu carga de trabajo

cr0x@server:~$ iostat -x 5 3
Linux 6.8.0 (server)  12/25/2025  _x86_64_  (32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.12    0.00    2.41   18.77    0.00   73.70

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s w_await aqu-sz  %util
sda              92.0  184320.0     0.0   0.00   28.44  2003.5      6.2     512.0  12.21   3.42   98.7
sdb              89.5  179200.0     0.0   0.00   31.02  2002.8      6.0     480.0  14.10   3.64   99.1

Significado: Discos saturados (~99% util), read await alto (28–31ms). Eso es normal para scrub en HDD, pero puede ser mortal para cargas sensibles a latencia.
Decisión: Si los usuarios se quejan o las VMs presentan picos de latencia, limita el impacto del scrub o prográmalo de noche. Si el await está alto incluso fuera de horas, investiga salud de discos/cableado.

Tarea 5: Encontrar el “tamaño real” de lo que el scrub debe leer (incluyendo snapshots)

cr0x@server:~$ zfs list -o name,used,usedbysnapshots,refer,avail -r tank
NAME                 USED  USEDBYSNAPSHOTS  REFER  AVAIL
tank                18.7T             6.2T   128K  12.1T
tank/vm             11.4T             4.8T  6.6T   12.1T
tank/home            2.1T             1.2T  0.9T   12.1T
tank/backups         5.2T             0.2T  5.0T   12.1T

Significado: El scrub lee bloques asignados; 6.2T son solo snapshots. Eso es tiempo extra de scrub por el que “olvidaste” que estabas pagando.
Decisión: Si los scrubs tardan demasiado, ajusta la retención de snapshots o separa datasets/pools por criticidad, no por sensaciones.

Tarea 6: Ver el historial de scrubs y si realmente los ejecutas

cr0x@server:~$ zpool history -il tank | tail -n 12
2025-12-23.01:12:43 zpool scrub tank
2025-11-23.01:09:51 zpool scrub tank
2025-10-23.01:11:02 zpool scrub tank
2025-09-22.01:08:37 zpool scrub tank

Significado: Alguien (o un temporizador) ha ejecutado scrubs mensuales. Si hay un hueco, has estado funcionando con esperanza.
Decisión: Pon los scrubs bajo un programador que puedas auditar (timers de systemd, cron) y alerta por “scrub atrasado”.

Tarea 7: Detectar errores de checksum temprano e identificar el vdev culpable

cr0x@server:~$ zpool status tank
  pool: tank
 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
  scan: scrub repaired 0B in 05:41:10 with 2 errors on Mon Dec 23 06:53:53 2025
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          mirror-0                  ONLINE       0     0     0
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     2
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0

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

        tank/vm@auto-2025-12-01:vm-103-disk-0

Significado: Dos errores de checksum y errores permanentes: ZFS no pudo reparar porque todas las copias estaban malas o la redundancia era insuficiente para esos bloques.
Decisión: Deja de fingir que esto está “bien.” Restaura los datos afectados desde backup/snapshots (si los snapshots están limpios) y comienza una investigación de hardware/ruta inmediatamente.

Tarea 8: Borrar contadores de error solo después de actuar

cr0x@server:~$ sudo zpool clear tank

Significado: Reinicia los contadores de error y borra el estado de “errores”. No arregla datos mágicamente.
Decisión: Borra solo después de: (1) capturar evidencia, (2) reemplazar/confirmar hardware, y (3) ejecutar un scrub posterior para validar la estabilidad. Si no, estás borrando la escena del crimen.

Tarea 9: Pausar o detener un scrub cuando molesta (y reanudar después)

cr0x@server:~$ sudo zpool scrub -p tank
cr0x@server:~$ zpool status tank
  pool: tank
 state: ONLINE
  scan: scrub paused since Mon Dec 23 10:04:11 2025
        7.12T scanned at 590M/s, 2.98T issued at 248M/s, 18.7T total
        0B repaired, 15.9% done, scrub paused
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
...

Significado: El scrub está pausado; el progreso se conserva según implementación y versión.
Decisión: Si la latencia está matando la producción, pausa y reanuda en una ventana tranquila en lugar de abortar todo.

cr0x@server:~$ sudo zpool scrub -s tank

Significado: Detiene el scrub.
Decisión: Usa stop cuando necesites cambiar hardware o cuando el propio scrub está provocando fallos que debes abordar primero (timeouts, resets).

Tarea 10: Distinguir scrub de resilver en la salida de status

cr0x@server:~$ zpool status 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 Tue Dec 24 02:01:17 2025
        1.44T scanned at 312M/s, 620G issued at 134M/s, 6.60T total
        620G resilvered, 9.16% done, 0 days 11:08:33 to go
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        DEGRADED     0     0     0
          mirror-0                  DEGRADED     0     0     0
            ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0
            replacing-1             DEGRADED     0     0     0
              ata-WDC_WD80EAZZ-00BKLB0  FAULTED     0     0     0  too many errors
              ata-WDC_WD80EAZZ-00BKLB0  ONLINE       0     0     0  (resilvering)

errors: No known data errors

Significado: Esto es un resilver, no un scrub. Perfil de riesgo distinto: estás reconstruyendo redundancia.
Decisión: Evita iniciar un scrub durante un resilver a menos que intentes validar un pool inestable y puedas permitir el I/O. Usualmente: deja que termine el resilver y luego haz un scrub.

Tarea 11: Ver registros de dispositivo (Linux) cuando scrubs provocan resets

cr0x@server:~$ sudo dmesg -T | tail -n 20
[Mon Dec 23 03:18:11 2025] ata9.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
[Mon Dec 23 03:18:11 2025] ata9.00: failed command: READ FPDMA QUEUED
[Mon Dec 23 03:18:11 2025] ata9: hard resetting link
[Mon Dec 23 03:18:12 2025] ata9: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[Mon Dec 23 03:18:14 2025] ata9.00: configured for UDMA/133

Significado: Resets de enlace durante lecturas intensas. Eso clama por problemas de cableado/backplane/HBA, no por “ZFS siendo quisquilloso.”
Decisión: Arregla la ruta física. El scrub solo es el mensajero que forzó lecturas sostenidas.

Tarea 12: Obtener datos SMART y decidir si reemplazar el disco

cr0x@server:~$ sudo smartctl -a /dev/sda | egrep -i "Reallocated|Pending|Offline_Uncorrectable|UDMA_CRC|Power_On_Hours"
  9 Power_On_Hours          0x0032   086   086   000    Old_age   Always       -       31254
 197 Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       8
 198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       8
 199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       14

Significado: Sectores pendientes/uncorrectable sugieren problemas reales de medio. Los errores UDMA CRC suelen apuntar a cableado/backplane.
Decisión: Si pending/uncorrectable > 0 y el scrub sacó errores de checksum: reemplaza el disco. Si solo suben CRC: vuelve a asentar/reemplaza el cable/puerto del backplane y sigue observando.

Tarea 13: Confirmar ashift y por qué importa para el tiempo de scrub

cr0x@server:~$ zdb -C tank | egrep "ashift|vdev_tree" -n | head
42:        vdev_tree:
57:            ashift: 12

Significado: ashift=12 implica sectores de 4K. Un ashift incorrecto (demasiado pequeño) puede causar amplificación RMW y comportamiento generalmente miserable.
Decisión: Si ashift está mal, no lo “tuneas.” Planifica una migración a un pool creado correctamente. El scrub no te salvará de un error fundamental.

Tarea 14: Identificar si un dataset está forzando I/O patológico durante el scrub

cr0x@server:~$ zfs get -o name,property,value -s local recordsize,compression,atime,dedup tank/vm
NAME     PROPERTY     VALUE
tank/vm  recordsize   128K
tank/vm  compression  lz4
tank/vm  atime        off
tank/vm  dedup        off

Significado: Valores por defecto razonables para muchas cargas de VM. Dedup off es una elección sensata para la mayoría de las organizaciones.
Decisión: Si ves dedup activado y los scrubs/reslivers son lentos con presión de memoria, investiga ARC/memoria y la presión del DDT. No adivines; mide.

Tarea 15: Verificar que el scrub no sea “rápido” porque no leyó mucho

cr0x@server:~$ zpool list -o name,size,alloc,free,fragmentation,health
NAME  SIZE   ALLOC  FREE  FRAG  HEALTH
tank  29.1T  18.7T  10.4T   42%  ONLINE

Significado: Allocado es 18.7T. Un scrub que “termina” en 15 minutos probablemente no leyó 18.7T; estás interpretando mal lo que pasó (o mirando el pool equivocado).
Decisión: Contrasta la duración del scrub con alloc y el throughput realista del dispositivo. Cuando los números no coinciden con la física, asume que te falta información.

Tarea 16: Usar logs de eventos para correlacionar errores de scrub con timestamps

cr0x@server:~$ sudo zpool events -v | tail -n 20
TIME                            CLASS
Dec 23 2025 03:18:12.123456789  ereport.fs.zfs.checksum
    zevent.fsname = tank
    zevent.vdev_path = /dev/disk/by-id/ata-WDC_WD80EAZZ-00BKLB0_XXXX
    zevent.vdev_guid = 1234567890123456789
Dec 23 2025 03:18:12.223456789  ereport.fs.zfs.io
    zevent.fsname = tank
    zevent.vdev_path = /dev/disk/by-id/ata-WDC_WD80EAZZ-00BKLB0_XXXX

Significado: ZFS te dice cuándo y dónde vio fallos de checksum/I/O.
Decisión: Correlaciona con dmesg y SMART. Si los eventos coinciden con resets de enlace, el “disco malo” podría ser una ruta mala.

Guía rápida de diagnóstico: encuentra el cuello de botella rápido

Cuando un scrub es lento o arroja errores, puedes pasar horas filosofando—o puedes hacer una triage rápida que lo reduzca a: disco, ruta, CPU/memoria o carga competidora.
Aquí está el orden práctico que ahorra tiempo.

Primero: ¿qué dice ZFS que está pasando?

  • Revisa: zpool status -v tank
  • Mira: “scrub in progress” vs “resilver”; bytes reparados; “errors: Permanent errors”; qué vdev muestra incrementos en READ/WRITE/CKSUM.
  • Decisión: Si aparecen errores permanentes, cambia de “rendimiento” a “modo recuperación de datos”. Captura evidencia, identifica objetos/datasets afectados, planea la restauración.

Segundo: ¿es inestabilidad de la ruta de hardware?

  • Revisa: dmesg -T | tail -n 200 en busca de resets/timeouts; smartctl para errores CRC; logs del HBA si están disponibles.
  • Mira: resets de enlace SATA, abortos SCSI, resets NVMe, spam de “I/O error” que aparece solo bajo carga de scrub.
  • Decisión: Si ocurren resets: trátalo primero como un problema de ruta (cables/backplane/HBA/expander/firmware). Reemplaza el componente sospechoso más barato antes de culpar a ZFS.

Tercero: ¿es saturación simple de I/O o contención?

  • Revisa: iostat -x 5, además de la telemetría que uses para latencia.
  • Mira: 100% util, await alto, profundidad de cola subiendo y si las escrituras también sufren.
  • Decisión: Si es “saturación normal”, gestionalo: programa, limita o aísla cargas. Si el await es extremo incluso con baja util, sospecha firmware/problemas del disco.

Cuarto: ¿ZFS o el SO están desabastecidos (CPU, RAM, presión de ARC)?

  • Revisa: vmstat 5, presión de memoria, tamaño del ARC y si el sistema está intercambiando.
  • Mira: actividad de swap; tormentas de kswapd; CPU pegada en tiempo sistema.
  • Decisión: Si estás intercambiando durante el scrub, arregla la memoria primero. El scrub es una carga de lectura; no debería convertir tu servidor en una demo de paginación.

Quinto: ¿es “lento porque tiene mucho que leer”?

  • Revisa: zfs list (usedbysnapshots) y zpool list alloc.
  • Mira: crecimiento de snapshots, asignación inesperada o fragmentación que implique muchas búsquedas.
  • Decisión: Si el pool es simplemente grande y activo, acepta scrubs más largos pero ajusta la programación y las alertas. La fiabilidad no es gratis; se factura en IOPS.

Tres micro-historias corporativas desde las trincheras del scrub

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

Una empresa mediana ejecutaba ZFS en un par de servidores de almacenamiento que respaldaban virtualización. Espejos por todos lados. Se sentían seguros, que es una condición común antes de aprender.
Los scrubs eran “opcionales”, porque el almacenamiento era “RAID1 y discos enterprise”.

Un disco falló durante una semana ocupada. Empezó un resilver. A mitad de camino, el pool comenzó a registrar errores de checksum en la cara superviviente de un espejo.
El equipo asumió: “ZFS está dramático; se sanará.” Esa suposición fue el incidente.

ZFS no pudo sanar esos bloques porque la única copia restante estaba mal. Los bloques corruptos eran antiguos—semanas—reposando en un área rara vez leída de un disco de VM.
Nadie lo notó hasta que el resilver forzó la lectura de todo y exigió corrección.

La falla operativa no fue “un disco murió.” Los discos mueren. La falla fue aceptar integridad desconocida durante semanas porque no se programaron ni monitorearon scrubs.
Tenían backups, pero las restauraciones eran lentas y políticamente dolorosas. El incidente llegó a nivel ejecutivo.

Después, no solo añadieron un scrub mensual. Añadieron una política: cualquier error de checksum distinto de cero crea un ticket, requiere triage de hardware y termina con un scrub limpio antes de cerrar.
El incidente dejó de ser “corrupción misteriosa de ZFS” y pasó a ser “encontramos una ruta mala antes de que nos arruinara el día.”

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

Otra organización tenía un pool HDD grande que scrubbeaba lentamente. Los usuarios se quejaban de lentitud los lunes por la mañana.
Alguien propuso una optimización: ejecutar scrub continuamente pero “niceándolo” limitando CPU y dejándolo gotear. También movieron la ventana de scrub a horas laborales porque “será suave.”

En el papel, suave. En realidad, creó contención de bajo grado permanente. El scrub nunca obtuvo suficiente tiempo contiguo para terminar rápido, así que se superpuso con todos los picos.
Los picos de latencia no eran dramáticos; eran constantes. Eso es peor. La gente tolera tormentas; se van por llovizna constante.

Mientras tanto, scrubs que duran eternamente aumentan la exposición. Cuanto más tiempo el pool está bajo escaneo sostenido, más probable es que colidess con fallos no relacionados:
espasmos del controlador, rarezas de firmware o simplemente el disco desafortunado que elige esa semana para empezar a hacer timeouts.

Eventualmente volvieron a un scrub estricto fuera de horas con parada forzada al final de la ventana de mantenimiento, luego reanudar la noche siguiente.
Mismo trabajo total, menos dolor para usuarios, finalización más rápida y menos incidentes de “scrub coincidió con algo raro”.

La lección: “siempre activo pero lento” no es automáticamente más seguro. Terminar un scrub es un hito de fiabilidad. Goteo de un scrub durante horas laborales es cómo inventas una nueva línea base de mediocridad.

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

Un equipo de servicios financieros ejecutaba ZFS en vdevs en espejo para almacenamiento de VMs. Nada exótico. Lo que sí tenían era una rutina sosa:
scrubs quincenales, alertas al completar y ticket si cualquier contador CKSUM cambiaba.
También registraban la duración del scrub y la comparaban con líneas base históricas.

Un ciclo, el scrub terminó pero tardó notablemente más. Sin errores, solo más lento. La alerta no saltó una paginación, pero creó un ticket de investigación porque la duración rompió un umbral.
Un ingeniero miró iostat durante el siguiente scrub y vio un disco con await más alto que su compañero espejo.

SMART no mostraba sectores realocados, pero sí CRCs en aumento. Cambiaron un cable y volvieron a asentar el disco en el backplane.
El siguiente scrub volvió a la velocidad normal. Aún sin errores.

Dos semanas después, esa misma ranura del backplane empezó a lanzar resets de enlace durante una ventana de alta IOPS—excepto que el equipo ya había marcado la ranura como sospechosa.
Redirigieron tráfico, reemplazaron el backplane y evitaron corrupción de datos y un incidente mayor.

La práctica aburrida no solo “encontró corrupción.” Encontró una ruta degradada antes de que cruzara la línea hacia pérdida de datos.
Eso es lo que parece la madurez operativa: menos restauraciones heroicas, más arreglos silenciosos.

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

La mayoría de los problemas de scrub no son exóticos. Son los mismos pocos modos de falla con diferentes disfraces.
Aquí está la lista corta que desearía que más runbooks tuvieran.

1) El scrub muestra errores de checksum, SMART parece “bien”

  • Síntoma: zpool status muestra CKSUM > 0, a veces “Permanent errors”. SMART muestra PASSED.
  • Causa raíz: SMART “PASSED” no es una garantía de salud. Además, la corrupción puede venir de la ruta (cable/HBA) o de la RAM, no solo del medio.
  • Solución: Correlaciona eventos ZFS con dmesg. Revisa errores CRC. Ejecuta un scrub de seguimiento después de re-asentar/reemplazar cables o mover el disco a otro puerto. Si los errores persisten en el mismo disco a través de puertos, reemplaza el disco.

2) Los scrubs “tardan un siglo” después de que aumentaron los snapshots

  • Síntoma: Tiempo de scrub duplicado en meses; sin cambios de hardware; pool parece bien por lo demás.
  • Causa raíz: La retención de snapshots aumentó los bloques asignados. El scrub lee bloques referenciados por snapshots, aunque el dataset activo sea pequeño.
  • Solución: Inspecciona usedbysnapshots. Ajusta la retención o mueve snapshots de larga retención a otro pool/tier de media. Re-baselinea la duración del scrub una vez saneada la política de snapshots.

3) El scrub causa picos de latencia en VMs y tickets de “almacenamiento lento”

  • Síntoma: Durante el scrub, la latencia sube; usuarios se quejan; bases de datos se atascan; VMs “se congelan” brevemente.
  • Causa raíz: HDDs saturados por lecturas de scrub; profundidad de cola sube; escrituras síncronas esperan detrás del I/O del scrub.
  • Solución: Programa scrubs fuera de horas. Considera limitar mediante tunables del SO/ZFS disponibles en tu plataforma. Si es un problema crónico, la solución real es más discos, SSDs o separar pools por carga de trabajo.

4) El scrub sigue “reparando” una pequeña cantidad en cada ejecución

  • Síntoma: Cada scrub reporta algunos bytes reparados, pero nada escala a una falla clara.
  • Causa raíz: Hardware marginal o ruta provocando lecturas intermitentemente malas; ZFS sana usando redundancia, enmascarando la pudrición subyacente hasta que empeora.
  • Solución: Trata reparaciones recurrentes como un incidente de hardware. Identifica el vdev con errores crecientes. Cambia cables/puertos, ejecuta tests SMART largos, reemplaza el dispositivo si el comportamiento lo sigue.

5) El scrub “termina al instante” en un pool enorme

  • Síntoma: Scrub terminado en minutos; el pool tiene decenas de TB asignados; nadie cree los números.
  • Causa raíz: Hiciste scrub al pool equivocado, estás leyendo estado desde otro host, o el pool tiene muy pocos datos asignados (thin allocation, mayormente libre).
  • Solución: Confirma zpool list alloc, confirma el nombre del pool, confirma que estás en la máquina correcta, revisa el historial y valida timestamps de estado.

6) Aparecen errores permanentes y alguien los limpia inmediatamente

  • Síntoma: “errors: Permanent errors” aparece y luego desaparece tras zpool clear, pero no se realizó ninguna restauración.
  • Causa raíz: Tratar el estado de error como cosmético; presión por dejar los dashboards en verde.
  • Solución: Política: nunca limpiar antes de capturar zpool status -v, identificar objetos impactados e intentar restaurar. Requiere un scrub limpio después de la remediación antes de cerrar tickets.

7) La velocidad del scrub colapsa después de agregar una caché “más rápida” o dispositivo especial

  • Síntoma: Tras cambios (L2ARC, special vdev), el tiempo de scrub y la latencia empeoran.
  • Causa raíz: La colocación de metadatos y la asimetría de dispositivos pueden cambiar patrones de I/O. Un special vdev demasiado pequeño o estresado puede convertirse en cuello de botella.
  • Solución: Mide la utilización a nivel de dispositivo durante scrub. Si un special vdev está saturado, ampliarlo o rediseñar. No añadas “aceleración” al pool sin planear comportamiento de scrub/resilver.

8) El scrub provoca timeouts de dispositivo solo bajo carga

  • Síntoma: Cargas normales bien. El scrub provoca errores I/O, resets, offlining.
  • Causa raíz: Firmware marginal, sobrecalentamiento, problemas de alimentación o una ruta que falla bajo throughput sostenido.
  • Solución: Revisa temperaturas, alimentación, cableado, firmware del HBA. Ejecuta tests SMART largos. Considera reducir carga concurrente (programar scrubs) mientras arreglas el hardware subyacente.

Chiste #2: El scrub no “causa” que tus discos fallen; simplemente les pide que hagan su trabajo durante más de cinco minutos.

Listas de verificación / plan paso a paso

Checklist A: Define una política de scrub defendible

  1. Elige una frecuencia basada en riesgo: comienza con cada 2–4 semanas para pools de producción.
  2. Define un umbral de “atrasado” (p. ej., 2× tu intervalo) que dispare una alerta/ticket.
  3. Define el impacto aceptable del scrub: ventana máxima, programación fuera de horas, reglas de pausa.
  4. Escribe qué significa operativamente “errores distintos de cero”: quién se pagina, quién investiga, cómo se prueba el cierre.
  5. Establece la línea base de duración y throughput del scrub; alerta sobre regresiones, no solo fallos.

Checklist B: Runbook operativo para cada ciclo de scrub

  1. Antes de empezar: zpool status (confirma ONLINE y anota contadores de error existentes).
  2. Inicia scrub: zpool scrub tank.
  3. Durante el scrub: monitoriza zpool status -v e iostat -x por impacto.
  4. Si hay dolor de rendimiento: pausa (zpool scrub -p) y reanuda en horas tranquilas.
  5. Tras completar: captura la salida de zpool status -v para registros.
  6. Si repaired > 0 o CKSUM > 0: abre un ticket de incidente; recolecta SMART + dmesg + zpool events; planea remediación.
  7. Después de la remediación: ejecuta un scrub de seguimiento y exige que complete limpio.

Checklist C: Cuando el scrub reporta errores permanentes

  1. Deja de hacer cambios. Captura: zpool status -v, zpool events -v, dmesg -T, datos SMART de todos los miembros.
  2. Identifica objetos/archivos impactados listados en status; mapéalos a datasets/servicios.
  3. Decide la ruta de recuperación: restaurar desde backup, desde snapshot antiguo o reconstruir VM/dataset afectado.
  4. Aborda la causa probable (reemplaza disco, arregla la ruta, revisa memoria si el patrón sugiere corrupción en RAM).
  5. Ejecuta un scrub tras las reparaciones y solo entonces borra errores si es necesario por higiene.

Ejemplo: programar con timers de systemd (aburrido, efectivo)

cr0x@server:~$ cat /etc/systemd/system/zfs-scrub@.service
[Unit]
Description=ZFS scrub on %i

[Service]
Type=oneshot
ExecStart=/sbin/zpool scrub %i
cr0x@server:~$ cat /etc/systemd/system/zfs-scrub@tank.timer
[Unit]
Description=Run ZFS scrub on tank monthly

[Timer]
OnCalendar=monthly
Persistent=true

[Install]
WantedBy=timers.target
cr0x@server:~$ sudo systemctl enable --now zfs-scrub@tank.timer
Created symlink /etc/systemd/system/timers.target.wants/zfs-scrub@tank.timer → /etc/systemd/system/zfs-scrub@tank.timer.

Significado: Ahora tienes una programación auditable. “Persistent=true” ejecuta timers perdidos tras un downtime.
Decisión: Añade monitorización que compruebe la última vez y el resultado del scrub. Programar sin visibilidad es solo optimismo con timestamps.

Preguntas frecuentes

1) ¿Debería ejecutar un scrub en un pool degradado?

A veces. Si sospechas corrupción silenciosa, un scrub puede revelar el alcance. Pero también estresa los dispositivos restantes.
Si el pool está degradado porque falta un disco y tienes un reemplazo listo, prioriza el reemplazo/resilver primero, luego el scrub.

2) ¿Es el scrub lo mismo que tests SMART largos?

No. Los tests SMART largos son diagnósticos a nivel de dispositivo. El scrub es validación de integridad de extremo a extremo a través de filesystem, controlador y disco.
Ejecuta ambos. Detectan clases diferentes de fallo.

3) ¿El scrub valida el espacio libre?

Generalmente no; lee bloques asignados (incluyendo snapshots). El espacio libre no es datos. El riesgo está en los bloques que podrías necesitar leer después, que son los asignados.

4) ¿Por qué el scrub se ralentiza al final?

El scrub inicial tiende a golpear regiones contiguas grandes y caches; las fases finales pueden involucrar metadatos más fragmentados y bloques dispersos, lo que aumenta las búsquedas y reduce el throughput—especialmente en HDDs.

5) Si el scrub reparó datos, ¿estoy a salvo ahora?

Más seguro, no a salvo. Las reparaciones significan que la redundancia funcionó, pero algo causó lecturas malas. Trata las reparaciones como una advertencia de que tu pool está consumiendo redundancia para ocultar un problema.
Investiga el hardware y ejecuta un scrub de seguimiento.

6) ¿Puedo hacer scrub con demasiada frecuencia?

Puedes hacer scrubs tan seguido que siempre estés compitiendo con tu propio trabajo de mantenimiento. Eso no es “más seguro”, es simplemente latencia auto-infligida.
Si tus scrubs se solapan continuamente, o el pool está demasiado ocupado, demasiado lento o la retención de snapshots está fuera de control.

7) ¿Cuál es la diferencia entre READ/WRITE/CKSUM en zpool status?

Aproximadamente: READ/WRITE sugieren fallos de I/O (timeouts, errores de dispositivo). CKSUM sugiere que se leyó dato pero no coincidió con el checksum esperado (puede ser medio, ruta, controlador, RAM).
Los errores CKSUM son los que deberían hacerte especialmente escéptico ante “pero el disco dice que está bien.”

8) ¿Debo hacer scrub después de reemplazar un disco?

Sí, después de que el resilver complete. El resilver reconstruye redundancia; el scrub valida la corrección de extremo a extremo en todo lo asignado.
Es la diferencia entre “lo reconstruimos” y “lo verificamos”.

9) ¿Necesito scrub si tengo backups?

Sí. Los backups son para recuperación, los scrubs para detección temprana. Sin scrubs, puede que solo descubras corrupción al intentar restaurar—a menudo mucho después de la última copia conocida buena.

10) ¿Cómo se si debo reemplazar un disco tras errores de scrub?

Si los errores siguen al disco a través de puertos/cables, reemplaza el disco. Si los errores siguen al puerto/cable/ranura del backplane, arregla la ruta.
Errores corregibles repetidos no son “aceptables.” Son un temporizador regresivo con duración desconocida.

Conclusión: próximos pasos que puedes hacer hoy

Un scrub ZFS es un control de la realidad. Demuestra que lo que has almacenado aún puede leerse y validarse—de extremo a extremo—en este momento.
Esa prueba importa más justo antes de que algo falle, por eso lo programas antes de sentir que lo necesitas.

Haz esto

  1. Elige una frecuencia: por defecto cada 2–4 semanas para pools de producción; aprieta si los pools son grandes o los resilvers son lentos.
  2. Programa scrubs con una herramienta auditable (timer de systemd/cron) y alerta por “atrasado” y por “errores”.
  3. Establece la línea base de duración y throughput del scrub, luego alerta por regresiones—lo lento suele ser el primer síntoma.
  4. Escribe una política de escalado para cualquier error de checksum distinto de cero o bytes reparados.
  5. Después de cualquier cambio de hardware (disco, cable, HBA), ejecuta un scrub en una ventana controlada y confirma que termina limpio.

El informe postmortem de un futuro outage dirá “lo encontramos durante un scrub rutinario” o “lo descubrimos durante una reconstrucción.”
Uno de esos se lee mejor ante la dirección. Más importante: uno suele ser sobrevivible.

← Anterior
MySQL vs MariaDB max_connections: evita los fallos OOM en servidores pequeños
Siguiente →
Errores de checksum ZFS en Proxmox: disco o cable — cómo demostrarlo

Deja un comentario